diff --git a/README.md b/README.md index 1f56a9e..0271d10 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ We encourage you to share your progress and ask questions in the Discussions sec | Day #15 | [Valid Anagram](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-15_Valid-Anagram) | :white_check_mark: | | Day #16 | [Nim Game](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-16_Nim-Game) | :white_check_mark: | | Day #17 | [Prison Break](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-17_Prison-Break) | :white_check_mark: | -| Day #18 | [Unique Paths](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-18_Unique-Paths) | :white_large_square: | +| Day #18 | [Unique Paths](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-18_Unique-Paths) | :white_check_mark: | | Day #19 | [URL Shortener](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-19_URL-Shortener) | :white_large_square: | | Day #20 | [API Challenge](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-20_API-Challenge) | :white_large_square: | | Day #21 | [Random Maze Generator](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-21_Random-Maze-Generator) | :white_large_square: | diff --git a/Week-03/Day-18_Unique-Paths/day18/Cargo.toml b/Week-03/Day-18_Unique-Paths/day18/Cargo.toml new file mode 100644 index 0000000..ebcf320 --- /dev/null +++ b/Week-03/Day-18_Unique-Paths/day18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day18" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/Week-03/Day-18_Unique-Paths/day18/src/lib.rs b/Week-03/Day-18_Unique-Paths/day18/src/lib.rs new file mode 100644 index 0000000..fa1af2f --- /dev/null +++ b/Week-03/Day-18_Unique-Paths/day18/src/lib.rs @@ -0,0 +1,28 @@ +use std::collections::HashMap; + +pub fn unique_paths(m: u8, n: u8) -> u16 { + let mut memo: HashMap> = HashMap::new(); + memo.entry(1).or_default().insert(1, 1); + count_unique_paths(m, n, &mut memo) +} + +fn count_unique_paths(m: u8, n: u8, memo: &mut HashMap>) -> u16 { + let memo_m = memo.get(&m); + let memo_n = memo_m.and_then(|m_m| m_m.get(&n)); + + if let Some(&result) = memo_n { + result + } else if m == 1 { + let result = unique_paths(m, n - 1); + memo.entry(m).or_default().insert(n, result); + result + } else if n == 1 { + let result = unique_paths(m - 1, n); + memo.entry(m).or_default().insert(n, result); + result + } else { + let result = unique_paths(m, n - 1) + unique_paths(m - 1, n); + memo.entry(m).or_default().insert(n, result); + result + } +} diff --git a/Week-03/Day-18_Unique-Paths/day18/src/main.rs b/Week-03/Day-18_Unique-Paths/day18/src/main.rs new file mode 100644 index 0000000..6574bf8 --- /dev/null +++ b/Week-03/Day-18_Unique-Paths/day18/src/main.rs @@ -0,0 +1,27 @@ +use std::io::{self, Write}; + +use day18::unique_paths; + +fn get_number(request: &str) -> u8 { + let mut buffer = String::new(); + + print!("{}", request); + io::stdout().flush().expect("Failed to flush stout"); + + io::stdin() + .read_line(&mut buffer) + .expect("Failed to read from stdin"); + + buffer.trim().parse().expect("The input is not a number") +} + +fn main() { + let m = get_number("Insert the height: "); + let n = get_number("Insert the width: "); + let result = unique_paths(m, n); + + println!( + "There are {} unique paths from ({}, {}) to (1, 1)", + result, m, n + ); +} diff --git a/Week-03/Day-18_Unique-Paths/day18/tests/examples.rs b/Week-03/Day-18_Unique-Paths/day18/tests/examples.rs new file mode 100644 index 0000000..0593c65 --- /dev/null +++ b/Week-03/Day-18_Unique-Paths/day18/tests/examples.rs @@ -0,0 +1,24 @@ +#[cfg(test)] +mod examples { + use day18::unique_paths; + + #[test] + fn example1() { + assert_eq!(unique_paths(3, 7), 28); + } + + #[test] + fn example2() { + assert_eq!(unique_paths(3, 2), 3); + } + + #[test] + fn example3() { + assert_eq!(unique_paths(7, 3), 28); + } + + #[test] + fn example4() { + assert_eq!(unique_paths(3, 3), 6); + } +}