merged update
This commit is contained in:
parent
9a0a9afe37
commit
e06c9db089
168
src/main.rs
168
src/main.rs
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue