From 7118165568af776ccca3d10b5828443605c4dddd Mon Sep 17 00:00:00 2001 From: Jonas Zeunert Date: Tue, 20 Feb 2024 13:48:10 +0100 Subject: [PATCH] Impl: Calculate Box Size --- src/playfield.rs | 24 +++++++++++++++++++++--- src/sudoku_solver.rs | 44 ++++++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/playfield.rs b/src/playfield.rs index 5055284..b167c28 100644 --- a/src/playfield.rs +++ b/src/playfield.rs @@ -60,8 +60,20 @@ impl Playfield { .map(|row| row[col_index].clone()) .collect() } - pub fn get_box(&self, row: usize, col: usize) -> Vec<&Field> { - let result: Vec<&Field> = Vec::new(); + pub fn get_box(&self, row: usize, col: usize) -> Vec { + let mut result: Vec = Vec::new(); + + let row_boundary_l = col - col % self.box_size; + let row_boundary_r = row_boundary_l + self.box_size; + let col_boundary_l = col - col % self.box_size; + let col_boundary_r = col_boundary_l + self.box_size; + + for i in row_boundary_l..row_boundary_r { + for j in col_boundary_l..col_boundary_r { + let field = self.fields[i][j].clone(); + result.push(field); + } + } result } @@ -140,7 +152,13 @@ mod tests { #[test] fn simple() { let playfield = Playfield::new(&"1 2 3 4 4 3 2 1 3 2 1 4 2 1 4 3".to_string(), 4); - let expected = vec![Field::new(1), Field::new(2), Field::new(4), Field::new(5)]; + let expected_1 = vec![Field::new(1), Field::new(2), Field::new(4), Field::new(3)]; + let result_1 = playfield.get_box(0, 0); + assert_eq!(result_1, expected_1); + + let expected_2 = vec![Field::new(2), Field::new(1), Field::new(4), Field::new(3)]; + let result_2 = playfield.get_box(3, 1); + assert_eq!(result_2, expected_2); } } mod calculate_box_size { diff --git a/src/sudoku_solver.rs b/src/sudoku_solver.rs index 9178306..4cf160e 100644 --- a/src/sudoku_solver.rs +++ b/src/sudoku_solver.rs @@ -28,11 +28,13 @@ impl SudokuSolver { let (row_idx, col_idx) = self.playfield.convert_index(*open_field); let row = &self.playfield.fields[row_idx]; - let possible_values_row = possible_values_from_vec(row, self.playfield.size as u32); + let possible_values_row = + SudokuSolver::possible_values_from_vec(row, self.playfield.size as u32); let col_index = open_field % self.playfield.size; let col = self.playfield.get_column(col_idx); - let possible_values_col = possible_values_from_vec(&col, self.playfield.size as u32); + let possible_values_col = + SudokuSolver::possible_values_from_vec(&col, self.playfield.size as u32); let possible_values = possible_values_row .intersection(&possible_values_col) @@ -44,21 +46,20 @@ impl SudokuSolver { field.possible_values = possible_values; } } -} + fn possible_values_from_vec(row: &Vec, max_value: u32) -> HashSet { + let possible_values: HashSet = (1..max_value + 1).collect(); -fn possible_values_from_vec(row: &Vec, max_value: u32) -> HashSet { - let possible_values: HashSet = (1..max_value + 1).collect(); + let populated_values: HashSet = row + .iter() + .filter(|field| field.value.is_some()) + .map(|v| v.value.unwrap()) + .collect(); - let populated_values: HashSet = row - .iter() - .filter(|field| field.value.is_some()) - .map(|v| v.value.unwrap()) - .collect(); - - possible_values - .difference(&populated_values) - .map(|v| *v) - .collect() + possible_values + .difference(&populated_values) + .map(|v| *v) + .collect() + } } #[cfg(test)] @@ -113,6 +114,10 @@ mod tests { assert!(field_3_values.iter().all(|i| expected_3.contains(i))); assert!(field_4_values.iter().all(|i| expected_4.contains(i))); } + #[test] + fn populate_from_box() { + let solver = &mut setup_solver("1 2 0 0 3 0 0 0 0 0 0 0 0 0 0 0", 4); + } } mod possible_values_from_vec { use super::super::*; @@ -125,9 +130,12 @@ mod tests { let expected_row_2 = vec![1, 2]; let expected_row_3 = vec![1, 2, 3]; - let possible_values_row_1 = possible_values_from_vec(&playfield.fields[0], 3); - let possible_values_row_2 = possible_values_from_vec(&playfield.fields[1], 3); - let possible_values_row_3 = possible_values_from_vec(&playfield.fields[2], 3); + let possible_values_row_1 = + SudokuSolver::possible_values_from_vec(&playfield.fields[0], 3); + let possible_values_row_2 = + SudokuSolver::possible_values_from_vec(&playfield.fields[1], 3); + let possible_values_row_3 = + SudokuSolver::possible_values_from_vec(&playfield.fields[2], 3); assert_eq!(possible_values_row_1, expected_row_1); assert!(possible_values_row_2