Skip to content

Commit

Permalink
Add problem 1639: Number of Ways to Form a Target String Given a Dict…
Browse files Browse the repository at this point in the history
…ionary
  • Loading branch information
EFanZh committed Oct 6, 2023
1 parent a848390 commit fb69cf7
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,7 @@ pub mod problem_1632_rank_transform_of_a_matrix;
pub mod problem_1636_sort_array_by_increasing_frequency;
pub mod problem_1637_widest_vertical_area_between_two_points_containing_no_points;
pub mod problem_1638_count_substrings_that_differ_by_one_character;
pub mod problem_1639_number_of_ways_to_form_a_target_string_given_a_dictionary;
pub mod problem_1640_check_array_formation_through_concatenation;
pub mod problem_1641_count_sorted_vowel_strings;
pub mod problem_1642_furthest_building_you_can_reach;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl Solution {
pub fn num_ways(words: Vec<String>, target: String) -> i32 {
// Count characters in each column.

let word_length = words.first().map_or(0, String::len);
let mut columns = vec![[0_u16; 26]; word_length].into_boxed_slice();

for word in words {
for (counts, c) in columns.iter_mut().zip(word.bytes()) {
counts[usize::from(c) - usize::from(b'a')] += 1;
}
}

// Dynamic programming.

let mut cache = vec![0_u32; target.len()].into_boxed_slice();

for counts in &*columns {
let mut top_left = 1;

for (target, c) in cache.iter_mut().zip(target.bytes()) {
let drop = u64::from(*target);
let pick = u64::from(top_left) * u64::from(counts[usize::from(c) - usize::from(b'a')]);

top_left = *target;
*target = ((drop + pick) % 1_000_000_007) as _;
}
}

*cache.last().unwrap() as _
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn num_ways(words: Vec<String>, target: String) -> i32 {
Self::num_ways(words, target)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl Solution {
pub fn num_ways(words: Vec<String>, target: String) -> i32 {
let word_length = words.first().map_or(0, String::len);
let mut cache = vec![0_u32; target.len()].into_boxed_slice();

for i in 0..word_length {
let mut counts = [0_u16; 26];

for word in &words {
counts[usize::from(word.as_bytes()[i]) - usize::from(b'a')] += 1;
}

let mut top_left = 1;

for (target, c) in cache.iter_mut().zip(target.bytes()) {
let drop = u64::from(*target);
let pick = u64::from(top_left) * u64::from(counts[usize::from(c) - usize::from(b'a')]);

top_left = *target;
*target = ((drop + pick) % 1_000_000_007) as _;
}
}

*cache.last().unwrap() as _
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn num_ways(words: Vec<String>, target: String) -> i32 {
Self::num_ways(words, target)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pub mod dynamic_programming;
pub mod dynamic_programming_2;

pub trait Solution {
fn num_ways(words: Vec<String>, target: String) -> i32;
}

#[cfg(test)]
mod tests {
use super::Solution;

pub fn run<S: Solution>() {
let test_cases = [
((&["acca", "bbbb", "caca"] as &[_], "aba"), 6),
((&["abba", "baab"], "bab"), 4),
];

for ((words, target), expected) in test_cases {
assert_eq!(
S::num_ways(words.iter().copied().map(str::to_string).collect(), target.to_string()),
expected,
);
}
}
}

0 comments on commit fb69cf7

Please sign in to comment.