From 3703e570bcf36a7fe7112cd8df2f291516a718dc Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Tue, 8 Oct 2024 17:06:39 +0100 Subject: [PATCH 1/3] Add two extra tests cases. --- exercise-book/src/green-yellow-game.md | 16 ++++++++++++++++ .../green-yellow/src/bin/complete.rs | 16 ++++++++++++++++ exercise-solutions/green-yellow/src/bin/step4.rs | 16 ++++++++++++++++ exercise-solutions/green-yellow/src/bin/step5.rs | 16 ++++++++++++++++ exercise-solutions/green-yellow/src/bin/step6.rs | 16 ++++++++++++++++ 5 files changed, 80 insertions(+) diff --git a/exercise-book/src/green-yellow-game.md b/exercise-book/src/green-yellow-game.md index 5787081..055b4d5 100644 --- a/exercise-book/src/green-yellow-game.md +++ b/exercise-book/src/green-yellow-game.md @@ -111,6 +111,22 @@ fn a_bit_of_everything() { "🟩⬜🟨🟨" ); } + +#[test] +fn two_in_guess_one_in_secret() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 3], &[3, 9, 9, 9]), + "⬜⬜🟨⬜" + ); +} + +#[test] +fn two_in_secret_one_in_guess() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 4], &[3, 3, 9, 9]), + "⬜⬜🟨⬜" + ); +} ``` ## Knowledge diff --git a/exercise-solutions/green-yellow/src/bin/complete.rs b/exercise-solutions/green-yellow/src/bin/complete.rs index 2782554..9b95934 100644 --- a/exercise-solutions/green-yellow/src/bin/complete.rs +++ b/exercise-solutions/green-yellow/src/bin/complete.rs @@ -147,3 +147,19 @@ fn a_bit_of_everything() { "🟩⬜🟨🟨" ); } + +#[test] +fn two_in_guess_one_in_secret() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 3], &[3, 9, 9, 9]), + "⬜⬜🟨⬜" + ); +} + +#[test] +fn two_in_secret_one_in_guess() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 4], &[3, 3, 9, 9]), + "⬜⬜🟨⬜" + ); +} diff --git a/exercise-solutions/green-yellow/src/bin/step4.rs b/exercise-solutions/green-yellow/src/bin/step4.rs index 66af63c..d836c4f 100644 --- a/exercise-solutions/green-yellow/src/bin/step4.rs +++ b/exercise-solutions/green-yellow/src/bin/step4.rs @@ -99,3 +99,19 @@ fn a_bit_of_everything() { "🟩⬜🟨🟨" ); } + +#[test] +fn two_in_guess_one_in_secret() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 3], &[3, 9, 9, 9]), + "⬜⬜🟨⬜" + ); +} + +#[test] +fn two_in_secret_one_in_guess() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 4], &[3, 3, 9, 9]), + "⬜⬜🟨⬜" + ); +} diff --git a/exercise-solutions/green-yellow/src/bin/step5.rs b/exercise-solutions/green-yellow/src/bin/step5.rs index 6d345df..c902ca6 100644 --- a/exercise-solutions/green-yellow/src/bin/step5.rs +++ b/exercise-solutions/green-yellow/src/bin/step5.rs @@ -108,3 +108,19 @@ fn a_bit_of_everything() { "🟩⬜🟨🟨" ); } + +#[test] +fn two_in_guess_one_in_secret() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 3], &[3, 9, 9, 9]), + "⬜⬜🟨⬜" + ); +} + +#[test] +fn two_in_secret_one_in_guess() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 4], &[3, 3, 9, 9]), + "⬜⬜🟨⬜" + ); +} diff --git a/exercise-solutions/green-yellow/src/bin/step6.rs b/exercise-solutions/green-yellow/src/bin/step6.rs index 80fca99..0cc8c34 100644 --- a/exercise-solutions/green-yellow/src/bin/step6.rs +++ b/exercise-solutions/green-yellow/src/bin/step6.rs @@ -143,3 +143,19 @@ fn a_bit_of_everything() { "🟩⬜🟨🟨" ); } + +#[test] +fn two_in_guess_one_in_secret() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 3], &[3, 9, 9, 9]), + "⬜⬜🟨⬜" + ); +} + +#[test] +fn two_in_secret_one_in_guess() { + assert_eq!( + &calc_green_and_yellow(&[1, 2, 3, 4], &[3, 3, 9, 9]), + "⬜⬜🟨⬜" + ); +} From 3c5648dd5cddb5dbc4959fc32f92216a538f928c Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Tue, 8 Oct 2024 17:06:47 +0100 Subject: [PATCH 2/3] Note that std::random is coming. --- exercise-book/src/green-yellow-game.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercise-book/src/green-yellow-game.md b/exercise-book/src/green-yellow-game.md index 055b4d5..66fa4b8 100644 --- a/exercise-book/src/green-yellow-game.md +++ b/exercise-book/src/green-yellow-game.md @@ -215,6 +215,8 @@ Let's do this by copying the input, so we can make it mutable, and mark off any Add `rand = "0.8"` to your Cargo.toml, and make a random number generator with `rand::thread_rng()` (Random Number Generator). You will also have to `use rand::Rng;` to bring the trait into scope. +(A built-in [random number generator](https://github.com/rust-lang/rust/issues/130703) is proposed for the Standard Library but is still nightly only as of October 2024). + Call `your_rng.gen_range()` in a loop.
From 70244134f6682ffbe8692fe304fb095f1c4638fa Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Tue, 8 Oct 2024 17:08:40 +0100 Subject: [PATCH 3/3] Fix the green-yellow tests. Also comment the solution, and avoid the need to clone the inputs. --- .../green-yellow/src/bin/complete.rs | 29 +++++++++++++----- .../green-yellow/src/bin/step4.rs | 29 +++++++++++++----- .../green-yellow/src/bin/step5.rs | 29 +++++++++++++----- .../green-yellow/src/bin/step6.rs | 30 +++++++++++++------ 4 files changed, 84 insertions(+), 33 deletions(-) diff --git a/exercise-solutions/green-yellow/src/bin/complete.rs b/exercise-solutions/green-yellow/src/bin/complete.rs index 9b95934..5ed411d 100644 --- a/exercise-solutions/green-yellow/src/bin/complete.rs +++ b/exercise-solutions/green-yellow/src/bin/complete.rs @@ -4,21 +4,34 @@ use rand::Rng; fn calc_green_and_yellow(guess: &[u8; 4], secret: &[u8; 4]) -> String { let mut result = ["⬜"; 4]; - let mut guess = guess.clone(); - let mut secret = secret.clone(); + let mut secret_handled = [false; 4]; for i in 0..guess.len() { if guess[i] == secret[i] { + // that's a match result[i] = "🟩"; - secret[i] = 0; - guess[i] = 0; + // don't match this secret digit again + secret_handled[i] = true; } } - for i in 0..guess.len() { - for j in 0..secret.len() { - if guess[i] == secret[j] && secret[j] != 0 && guess[i] != 0 { - result[i] = "🟨"; + 'guess: for g_idx in 0..guess.len() { + // only process guess digits we haven't already dealt with + if result[g_idx] == "🟩" { + continue; + } + for s_idx in 0..secret.len() { + // only process secret digits we haven't already dealt with + if secret_handled[s_idx] { + continue; + } + if guess[g_idx] == secret[s_idx] { + // put a yellow block in for this guess + result[g_idx] = "🟨"; + // never match this secret digit again + secret_handled[s_idx] = true; + // stop comparing this guessed digit to any other secret digits + continue 'guess; } } } diff --git a/exercise-solutions/green-yellow/src/bin/step4.rs b/exercise-solutions/green-yellow/src/bin/step4.rs index d836c4f..158eac0 100644 --- a/exercise-solutions/green-yellow/src/bin/step4.rs +++ b/exercise-solutions/green-yellow/src/bin/step4.rs @@ -2,21 +2,34 @@ fn calc_green_and_yellow(guess: &[u8; 4], secret: &[u8; 4]) -> String { let mut result = ["⬜"; 4]; - let mut guess = *guess; - let mut secret = *secret; + let mut secret_handled = [false; 4]; for i in 0..guess.len() { if guess[i] == secret[i] { + // that's a match result[i] = "🟩"; - secret[i] = 0; - guess[i] = 0; + // don't match this secret digit again + secret_handled[i] = true; } } - for i in 0..guess.len() { - for j in 0..secret.len() { - if guess[i] == secret[j] && secret[j] != 0 && guess[i] != 0 { - result[i] = "🟨"; + 'guess: for g_idx in 0..guess.len() { + // only process guess digits we haven't already dealt with + if result[g_idx] == "🟩" { + continue; + } + for s_idx in 0..secret.len() { + // only process secret digits we haven't already dealt with + if secret_handled[s_idx] { + continue; + } + if guess[g_idx] == secret[s_idx] { + // put a yellow block in for this guess + result[g_idx] = "🟨"; + // never match this secret digit again + secret_handled[s_idx] = true; + // stop comparing this guessed digit to any other secret digits + continue 'guess; } } } diff --git a/exercise-solutions/green-yellow/src/bin/step5.rs b/exercise-solutions/green-yellow/src/bin/step5.rs index c902ca6..57d8d7f 100644 --- a/exercise-solutions/green-yellow/src/bin/step5.rs +++ b/exercise-solutions/green-yellow/src/bin/step5.rs @@ -4,21 +4,34 @@ use rand::Rng; fn calc_green_and_yellow(guess: &[u8; 4], secret: &[u8; 4]) -> String { let mut result = ["⬜"; 4]; - let mut guess = *guess; - let mut secret = *secret; + let mut secret_handled = [false; 4]; for i in 0..guess.len() { if guess[i] == secret[i] { + // that's a match result[i] = "🟩"; - secret[i] = 0; - guess[i] = 0; + // don't match this secret digit again + secret_handled[i] = true; } } - for i in 0..guess.len() { - for j in 0..secret.len() { - if guess[i] == secret[j] && secret[j] != 0 && guess[i] != 0 { - result[i] = "🟨"; + 'guess: for g_idx in 0..guess.len() { + // only process guess digits we haven't already dealt with + if result[g_idx] == "🟩" { + continue; + } + for s_idx in 0..secret.len() { + // only process secret digits we haven't already dealt with + if secret_handled[s_idx] { + continue; + } + if guess[g_idx] == secret[s_idx] { + // put a yellow block in for this guess + result[g_idx] = "🟨"; + // never match this secret digit again + secret_handled[s_idx] = true; + // stop comparing this guessed digit to any other secret digits + continue 'guess; } } } diff --git a/exercise-solutions/green-yellow/src/bin/step6.rs b/exercise-solutions/green-yellow/src/bin/step6.rs index 0cc8c34..62ce74f 100644 --- a/exercise-solutions/green-yellow/src/bin/step6.rs +++ b/exercise-solutions/green-yellow/src/bin/step6.rs @@ -5,28 +5,40 @@ use rand::Rng; #[allow(unused)] fn calc_green_and_yellow(guess: &[u8; 4], secret: &[u8; 4]) -> String { let mut result = ["⬜"; 4]; - let mut guess = *guess; - let mut secret = *secret; + let mut secret_handled = [false; 4]; for i in 0..guess.len() { if guess[i] == secret[i] { + // that's a match result[i] = "🟩"; - secret[i] = 0; - guess[i] = 0; + // don't match this secret digit again + secret_handled[i] = true; } } - for i in 0..guess.len() { - for j in 0..secret.len() { - if guess[i] == secret[j] && secret[j] != 0 && guess[i] != 0 { - result[i] = "🟨"; + 'guess: for g_idx in 0..guess.len() { + // only process guess digits we haven't already dealt with + if result[g_idx] == "🟩" { + continue; + } + for s_idx in 0..secret.len() { + // only process secret digits we haven't already dealt with + if secret_handled[s_idx] { + continue; + } + if guess[g_idx] == secret[s_idx] { + // put a yellow block in for this guess + result[g_idx] = "🟨"; + // never match this secret digit again + secret_handled[s_idx] = true; + // stop comparing this guessed digit to any other secret digits + continue 'guess; } } } result.join("") } - fn main() { let mut rng = rand::thread_rng(); let stdin = std::io::stdin();