merged update

This commit is contained in:
WanderingPenwing 2024-11-28 18:04:55 +01:00
parent 9a0a9afe37
commit e06c9db089

View file

@ -1,5 +1,5 @@
use std::fmt; use std::fmt;
use std::collections::HashSet; //use std::collections::HashSet;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
#[derive(Clone)] #[derive(Clone)]
@ -21,7 +21,7 @@ impl Cell {
self.possibilities = (1..=9).collect(); self.possibilities = (1..=9).collect();
} }
fn remove_possibilities(&mut self, possibilities: &HashSet<u8>) { fn remove_possibilities(&mut self, possibilities: &Vec<u8>) {
self.possibilities.retain(|&x| !possibilities.contains(&x)) self.possibilities.retain(|&x| !possibilities.contains(&x))
} }
} }
@ -87,63 +87,28 @@ impl Sudoku {
} }
fn update_possibilities(&mut self) { fn update_possibilities(&mut self) {
self.update_rows(); let mut row_used_values: [Vec<u8>;9] = [vec![],vec![],vec![],vec![],vec![],vec![],vec![],vec![],vec![]];
self.update_columns(); let mut column_used_values: [Vec<u8>;9] = [vec![],vec![],vec![],vec![],vec![],vec![],vec![],vec![],vec![]];
self.update_squares(); let mut square_used_values: [[Vec<u8>;3];3] = [[vec![],vec![],vec![]],[vec![],vec![],vec![]],[vec![],vec![],vec![]]];
}
fn update_rows(&mut self) { for row_index in 0..9 {
for row_index in 0..9 { for column_index in 0..9 {
let mut used_values: HashSet<u8> = HashSet::new(); let Some(value) = self.grid[row_index][column_index].value else {
continue
};
row_used_values[row_index].push(value);
column_used_values[column_index].push(value);
square_used_values[row_index/3][column_index/3].push(value);
}
}
for column_index in 0..9 { for row_index in 0..9 {
if let Some(value) = self.grid[row_index][column_index].value { for column_index in 0..9 {
used_values.insert(value); self.grid[row_index][column_index].remove_possibilities(&row_used_values[row_index]);
} self.grid[row_index][column_index].remove_possibilities(&column_used_values[column_index]);
} self.grid[row_index][column_index].remove_possibilities(&square_used_values[row_index/3][column_index/3]);
}
for column_index in 0..9 { }
self.grid[row_index][column_index].remove_possibilities(&used_values);
}
}
}
fn update_columns(&mut self) {
for column_index in 0..9 {
let mut used_values: HashSet<u8> = HashSet::new();
for row_index in 0..9 {
if let Some(value) = self.grid[row_index][column_index].value {
used_values.insert(value);
}
}
for row_index in 0..9 {
self.grid[row_index][column_index].remove_possibilities(&used_values);
}
}
}
fn update_squares(&mut self) {
for square_row_index in 0..3 {
for square_column_index in 0..3 {
let mut used_values: HashSet<u8> = HashSet::new();
for row_offset_index in 0..3 {
for column_offset_index in 0..3 {
if let Some(value) = self.grid[square_row_index * 3 + row_offset_index][square_column_index * 3 + column_offset_index].value {
used_values.insert(value);
}
}
}
for row_offset_index in 0..3 {
for column_offset_index in 0..3 {
self.grid[square_row_index * 3 + row_offset_index][square_column_index * 3 + column_offset_index].remove_possibilities(&used_values.clone());
}
}
}
}
} }
fn collapse(&mut self) -> bool { fn collapse(&mut self) -> bool {
@ -188,16 +153,14 @@ impl Sudoku {
} }
} }
if let Some(choice) = fork { let Some(choice) = fork else {
self.reset_possibilities();
let mut choice_value = HashSet::new();
choice_value.insert(choice.selected_value);
self.grid[choice.cell_selected[0]][choice.cell_selected[1]].remove_possibilities(&choice_value);
return self.collapse_cell(choice.cell_selected[0], choice.cell_selected[1])
} else {
println!("x backtracked to start"); println!("x backtracked to start");
return false return false
} };
self.reset_possibilities();
self.grid[choice.cell_selected[0]][choice.cell_selected[1]].remove_possibilities(&vec![choice.selected_value]);
return self.collapse_cell(choice.cell_selected[0], choice.cell_selected[1])
} }
fn reset_possibilities(&mut self) { fn reset_possibilities(&mut self) {
@ -211,26 +174,61 @@ impl Sudoku {
} }
fn collapse_cell(&mut self, row_index: usize, column_index: usize) -> bool { fn collapse_cell(&mut self, row_index: usize, column_index: usize) -> bool {
if let Some(&selected_value) = self.grid[row_index][column_index].possibilities.choose(&mut self.rng) { let Some(&selected_value) = self.grid[row_index][column_index].possibilities.choose(&mut self.rng) else {
self.history.push(Choice {
cell_selected: [row_index, column_index],
possibilities: self.grid[row_index][column_index].possibilities.clone(),
selected_value,
});
self.grid[row_index][column_index].set(selected_value);
println!("# collapsing [{}][{}] ({:?}) to {}", row_index, column_index, self.grid[row_index][column_index].possibilities, selected_value);
return true
} else {
println!("x no possibilities for [{}][{}]", row_index, column_index); println!("x no possibilities for [{}][{}]", row_index, column_index);
return false return false
};
self.history.push(Choice {
cell_selected: [row_index, column_index],
possibilities: self.grid[row_index][column_index].possibilities.clone(),
selected_value,
});
self.grid[row_index][column_index].set(selected_value);
println!("# collapsing [{}][{}] ({:?}) to {}", row_index, column_index, self.grid[row_index][column_index].possibilities, selected_value);
return true
}
fn solve(&mut self, display: bool) {
if display {
self.display();
println!("--------");
} }
}
self.update_possibilities();
let mut counter: usize = 0;
while self.collapse() {
self.update_possibilities();
counter +=1;
}
if display {
println!("--------");
println!("finished with {} steps", counter);
self.display();
}
}
} }
// [6,0,0,0,0,2,1,0,0], // has to backtrack
// [0,3,2,9,0,0,0,7,0],
// [0,0,0,0,0,8,0,0,0],
// [2,0,0,0,0,0,4,0,0],
// [7,0,3,0,0,0,9,1,0],
// [0,8,0,0,9,4,0,0,0],
// [0,0,4,0,0,0,6,0,0],
// [1,2,0,7,0,0,0,0,5],
// [0,0,0,0,0,0,0,9,4],
fn main() { fn main() {
let sudoku_set: [[u8; 9]; 9] = [ let sudoku_set: [[u8; 9]; 9] = [
[6,0,0,0,0,2,1,0,0], [0,0,0,0,0,0,0,0,0],
[0,3,2,9,0,0,0,7,0], [0,3,2,9,0,0,0,7,0],
[0,0,0,0,0,8,0,0,0], [0,0,0,0,0,8,0,0,0],
[2,0,0,0,0,0,4,0,0], [2,0,0,0,0,0,4,0,0],
@ -243,17 +241,5 @@ fn main() {
let mut sudoku = Sudoku::new(sudoku_set); let mut sudoku = Sudoku::new(sudoku_set);
sudoku.display(); sudoku.solve(true);
println!("--------");
sudoku.update_possibilities();
while sudoku.collapse() {
sudoku.update_possibilities();
}
println!("--------");
sudoku.display();
} }