diff --git a/src/main.rs b/src/main.rs index cd52b98..dda29e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -111,38 +111,27 @@ impl Sudoku { let mut collapsed_possibility = HashSet::new(); collapsed_possibility.insert(collapsed_state); - for column_index in 0..self.size { - if column_index == collapsed_column { - continue; + for index in 0..self.size { + if index != collapsed_column { + self.remove_allowed(collapsed_row, index, &collapsed_possibility)?; } - if self.grid[collapsed_row][column_index].get() == Some(collapsed_state) { - return Err(WaveError::Contradiction) + if index != collapsed_row { + self.remove_allowed(index, collapsed_column, &collapsed_possibility)?; } - self.remove_allowed(collapsed_row, column_index, &collapsed_possibility)?; - } - for row_index in 0..self.size { - if row_index == collapsed_row { - continue; - } - if self.grid[row_index][collapsed_column].get() == Some(collapsed_state) { - return Err(WaveError::Contradiction) + let square_row = (collapsed_row/self.square_size)*self.square_size + index/self.square_size; + let square_column = (collapsed_column/self.square_size)*self.square_size + index%self.square_size; + if square_row != collapsed_row || square_column != collapsed_column { + self.remove_allowed(square_row, square_column, &collapsed_possibility)?; } - self.remove_allowed(row_index, collapsed_column, &collapsed_possibility)?; - } - for row_index in 0..self.square_size { - for column_index in 0..self.square_size { - let row = (collapsed_row/self.square_size)*self.square_size + row_index; - let column = (collapsed_column/self.square_size)*self.square_size + column_index; - if row == collapsed_row && column == collapsed_column { - continue; - } - if self.grid[row][column].get() == Some(collapsed_state) { - return Err(WaveError::Contradiction) - } - self.remove_allowed(row, column, &collapsed_possibility)?; - } } + self.check_impossible(collapsed_row, collapsed_column)?; + + Ok(()) + } + + fn check_impossible(&self, collapsed_row: usize, collapsed_column: usize) -> Result<(),WaveError> { + let mut missing_states: HashSet = (1..=self.size).collect(); for column_index in 0..self.size { if let Some(state) = self.grid[collapsed_row][column_index].get() { @@ -195,8 +184,7 @@ impl Sudoku { } return Err(WaveError::Contradiction) } - - Ok(()) + Ok(()) } fn collapse(&mut self) -> Result<(), WaveError> { @@ -269,28 +257,19 @@ impl Sudoku { } fn propagate_backtrack(&mut self, cell_pos: [usize; 2], removed_state: usize) { - for row_index in 0..self.size { - if row_index == cell_pos[0] { - continue + for index in 0..self.size { + if index != cell_pos[0] { + self.grid[index][cell_pos[1]].add_allowed(removed_state); } - self.grid[row_index][cell_pos[1]].add_allowed(removed_state); - } - for column_index in 0..self.size { - if column_index == cell_pos[1] { - continue + if index != cell_pos[1] { + self.grid[cell_pos[0]][index].add_allowed(removed_state); } - self.grid[cell_pos[0]][column_index].add_allowed(removed_state); - } - for row_index in 0..self.square_size { - for column_index in 0..self.square_size { - let row = (cell_pos[0]/self.square_size)*self.square_size + row_index; - let column = (cell_pos[1]/self.square_size)*self.square_size + column_index; - if row == cell_pos[0] && column == cell_pos[1] { - continue - } - self.grid[row][column].add_allowed(removed_state); + let square_row = (cell_pos[0]/self.square_size)*self.square_size + index/self.square_size; + let square_column = (cell_pos[1]/self.square_size)*self.square_size + index%self.square_size; + if square_row != cell_pos[0] || square_column != cell_pos[1] { + self.grid[square_row][square_column].add_allowed(removed_state); } - } + } } fn reset_allowed(&mut self) { @@ -302,6 +281,11 @@ impl Sudoku { } fn remove_allowed(&mut self, row_index: usize, column_index: usize, set_to_remove: &HashSet) -> Result<(), WaveError> { + if let Some(state) = self.grid[row_index][column_index].get() { + if set_to_remove.contains(&state) { + return Err(WaveError::Contradiction) + } + } match self.grid[row_index][column_index].remove_allowed(set_to_remove) { Ok(result) => { let cell::RemoveResult::Collapsed(state) = result else {