diff --git a/src/playfield.rs b/src/playfield.rs index 99f7d54..5027262 100644 --- a/src/playfield.rs +++ b/src/playfield.rs @@ -22,7 +22,6 @@ impl Playfield { playfield } - fn parse(&mut self, field: &String) { let chars = field.split(" ").collect::>(); @@ -53,6 +52,9 @@ impl Playfield { } } } + pub fn get_column(&self, index: usize) -> Vec { + Vec::new() + } } impl fmt::Display for Playfield { @@ -97,6 +99,24 @@ mod tests { } } + mod get_column { + use super::*; + #[test] + fn simple() { + let playfield = Playfield::new(&"1 2 3 1 2 3 1 2 3".to_string(), 3); + let expected_1 = vec![Field::new(1); 3]; + let expected_2 = vec![Field::new(2); 3]; + let expected_3 = vec![Field::new(3); 3]; + + let column_1 = playfield.get_column(1); + let column_2 = playfield.get_column(2); + let column_3 = playfield.get_column(3); + + assert_eq!(column_1, expected_1); + assert_eq!(column_2, expected_2); + assert_eq!(column_3, expected_3); + } + } mod parse { use super::super::*; @@ -116,7 +136,7 @@ mod tests { vec![Field::default(), Field::default(), Field::default()], vec![Field::new(3), Field::new(2), Field::new(1)] ], - open_fields: vec![] + open_fields: vec![3, 4, 5] } ) } diff --git a/src/sudoku_solver.rs b/src/sudoku_solver.rs index d72cc7b..adc56ca 100644 --- a/src/sudoku_solver.rs +++ b/src/sudoku_solver.rs @@ -17,25 +17,35 @@ impl SudokuSolver { return self.playfield.clone(); } - fn populate_possible_values(&self) { - for open_field in &self.playfield.open_fields {} - } - fn possible_values_from_row(&self, row: &Vec) -> Vec { - let max_value = self.playfield.size as u32; - let possible_values: HashSet = (1..max_value + 1).collect(); + fn populate_possible_values(&mut self) { + for open_field in &self.playfield.open_fields { + let row_index = open_field / self.playfield.size; + let row = &mut self.playfield.fields[row_index]; + let col_index = open_field % self.playfield.size; - let populated_values: HashSet = row - .iter() - .filter(|field| field.value.is_some()) - .map(|v| v.value.unwrap()) - .collect(); + let possible_values = possible_values_from_row(row, self.playfield.size as u32); - possible_values - .symmetric_difference(&populated_values) - .map(|v| *v) - .collect() + let field = &mut row[col_index]; + field.possible_values = possible_values; + } } } + +fn possible_values_from_row(row: &Vec, max_value: u32) -> Vec { + 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(); + + possible_values + .symmetric_difference(&populated_values) + .map(|v| *v) + .collect() +} + #[cfg(test)] mod tests { use crate::sudoku_solver::SudokuSolver; @@ -53,36 +63,59 @@ mod tests { #[test] fn simple() { - let solver = setup_solver("1 2 3 2 3 1 3 1 0", 3); - let expected = create_test_playfield("1 2 3 2 3 1 3 1 2", 3); + let solver = setup_solver("1 0 3 4 4 0 2 0 0 1 0 2 2 4 0 3", 4); + let expected = create_test_playfield("1 2 3 4 4 3 2 1 3 1 4 2 2 4 1 3", 4); let solved = solver.solve(); assert_eq!(solved, expected); } } - mod populate_possible_values { - mod possible_values_from_row { - use super::super::*; + mod possible_values { + use super::*; + #[test] + fn simple() { + let solver = &mut setup_solver("1 0 0 3 0 0 2 3 1", 3); + let expected_1 = vec![2, 3]; + let expected_2 = vec![2, 3]; + let expected_3 = vec![1, 2]; + let expected_4 = vec![1, 2]; - #[test] - fn simple() { - let solver = setup_solver("1 2 0 3 0 0 0 0 0", 3); - let expected_row_1 = vec![3]; - let expected_row_2 = vec![1, 2]; - let expected_row_3 = vec![1, 2, 3]; + solver.populate_possible_values(); - let possible_values_row_1 = - solver.possible_values_from_row(&solver.playfield.fields[0]); - let possible_values_row_2 = - solver.possible_values_from_row(&solver.playfield.fields[1]); - let possible_values_row_3 = - solver.possible_values_from_row(&solver.playfield.fields[2]); + let field_1_values = &solver.playfield.fields[0][1].possible_values; + let field_2_values = &solver.playfield.fields[0][2].possible_values; + let field_3_values = &solver.playfield.fields[1][1].possible_values; + let field_4_values = &solver.playfield.fields[1][2].possible_values; - assert_eq!(possible_values_row_1, expected_row_1); - assert_eq!(possible_values_row_2, expected_row_2); - assert_eq!(possible_values_row_3, expected_row_3); - } + assert!(field_1_values.iter().all(|i| expected_1.contains(i))); + assert!(field_2_values.iter().all(|i| expected_2.contains(i))); + assert!(field_3_values.iter().all(|i| expected_3.contains(i))); + assert!(field_4_values.iter().all(|i| expected_4.contains(i))); + } + } + mod possible_values_from_row { + use super::super::*; + use super::*; + + #[test] + fn simple() { + let playfield = create_test_playfield("1 2 0 3 0 0 0 0 0", 3); + let expected_row_1 = vec![3]; + let expected_row_2 = vec![1, 2]; + let expected_row_3 = vec![1, 2, 3]; + + let possible_values_row_1 = possible_values_from_row(&playfield.fields[0], 3); + let possible_values_row_2 = possible_values_from_row(&playfield.fields[1], 3); + let possible_values_row_3 = possible_values_from_row(&playfield.fields[2], 3); + + assert_eq!(possible_values_row_1, expected_row_1); + assert!(possible_values_row_2 + .iter() + .all(|item| expected_row_2.contains(item))); + assert!(possible_values_row_3 + .iter() + .all(|item| expected_row_3.contains(item))); } } }