diff --git a/README.md b/README.md index a6d53c7..df8cd24 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ We encourage you to share your progress and ask questions in the Discussions sec | Day #13 | [Need Help With Your Packing](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-02/Day-13_Need-Help-With-Packing) | :white_check_mark: | | Day #14 | [The Karacas Encryption Algorithm](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-02/Day-14_Karacas-Encryption-Algorithm) | :white_check_mark: | | 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_large_square: | +| 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_large_square: | | Day #18 | [Unique Paths](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-18_Unique-Paths) | :white_large_square: | | Day #19 | [URL Shortener](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-19_URL-Shortener) | :white_large_square: | diff --git a/Week-03/Day-16_Nim-Game/day16/Cargo.toml b/Week-03/Day-16_Nim-Game/day16/Cargo.toml new file mode 100644 index 0000000..b2016c1 --- /dev/null +++ b/Week-03/Day-16_Nim-Game/day16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day16" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/Week-03/Day-16_Nim-Game/day16/src/lib.rs b/Week-03/Day-16_Nim-Game/day16/src/lib.rs new file mode 100644 index 0000000..bb7126e --- /dev/null +++ b/Week-03/Day-16_Nim-Game/day16/src/lib.rs @@ -0,0 +1,28 @@ +use std::collections::HashMap; + +pub fn nim_winner(n: usize) -> bool { + let mut memo: HashMap> = HashMap::new(); + nim_dp(n, true, &mut memo) +} + +pub fn nim_dp(moves: usize, turn: bool, memo: &mut HashMap>) -> bool { + if moves <= 3 { + return turn; + } + + if memo.contains_key(&moves) && memo[&moves].contains_key(&turn) { + return memo[&moves][&turn]; + } + + memo.insert(moves, HashMap::new()); + + for i in 1..=3 { + if nim_dp(moves - i, !turn, memo) { + memo.get_mut(&moves).unwrap().insert(turn, true); + return true; + } + } + + memo.get_mut(&moves).unwrap().insert(turn, false); + false +} diff --git a/Week-03/Day-16_Nim-Game/day16/src/main.rs b/Week-03/Day-16_Nim-Game/day16/src/main.rs new file mode 100644 index 0000000..b1830c7 --- /dev/null +++ b/Week-03/Day-16_Nim-Game/day16/src/main.rs @@ -0,0 +1,25 @@ +use std::io::{self, Write}; + +use day16::nim_winner; + +fn main() { + let mut buffer = String::new(); + + print!("How many stones will you have during your turn? "); + io::stdout().flush().expect("Failed to flush stdout."); + + io::stdin() + .read_line(&mut buffer) + .expect("Failed to read from stdin"); + + let stones = buffer + .trim() + .parse() + .expect("Your input is not a valid number"); + + if nim_winner(stones) { + println!("You will win!"); + } else { + println!("You will lose!"); + } +} diff --git a/Week-03/Day-16_Nim-Game/day16/tests/examples.rs b/Week-03/Day-16_Nim-Game/day16/tests/examples.rs new file mode 100644 index 0000000..ef14da5 --- /dev/null +++ b/Week-03/Day-16_Nim-Game/day16/tests/examples.rs @@ -0,0 +1,16 @@ +use day16::nim_winner; + +#[test] +fn example1() { + assert!(!nim_winner(4)); +} + +#[test] +fn example2() { + assert!(nim_winner(1)); +} + +#[test] +fn example3() { + assert!(nim_winner(2)); +}