|
@@ -21,14 +21,14 @@ use rand_chacha::ChaCha20Rng;
|
|
|
use rand::distributions::{Distribution, Uniform};
|
|
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
|
-pub struct Possible(u16);
|
|
|
+pub struct Bits(u16);
|
|
|
|
|
|
/// Set bits number of bits to 1 (true)
|
|
|
pub const fn set_bits(bits: u8) -> u16 {
|
|
|
(1 << (bits)) - 1
|
|
|
}
|
|
|
|
|
|
-impl Possible {
|
|
|
+impl Bits {
|
|
|
/// clear all bits
|
|
|
pub fn clear(&mut self) {
|
|
|
self.0 = 0;
|
|
@@ -61,21 +61,21 @@ impl Possible {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-struct PossibleIterator<'a> {
|
|
|
- possible: &'a Possible,
|
|
|
+struct BitsIterator<'a> {
|
|
|
+ possible: &'a Bits,
|
|
|
index: u8,
|
|
|
}
|
|
|
|
|
|
-impl Possible {
|
|
|
- fn iter(&self) -> PossibleIterator {
|
|
|
- PossibleIterator {
|
|
|
+impl Bits {
|
|
|
+ fn iter(&self) -> BitsIterator {
|
|
|
+ BitsIterator {
|
|
|
possible: self,
|
|
|
index: 1,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'a> Iterator for PossibleIterator<'a> {
|
|
|
+impl<'a> Iterator for BitsIterator<'a> {
|
|
|
type Item = u8;
|
|
|
|
|
|
fn next(&mut self) -> Option<u8> {
|
|
@@ -98,7 +98,7 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn check_possible_bitset() {
|
|
|
- let mut p = Possible(0);
|
|
|
+ let mut p = Bits(0);
|
|
|
|
|
|
p.clear();
|
|
|
|
|
@@ -113,7 +113,7 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn check_possible_iter() {
|
|
|
- let mut p = Possible(0);
|
|
|
+ let mut p = Bits(0);
|
|
|
p.set(3, true);
|
|
|
p.set(5, true);
|
|
|
p.set(6, true);
|
|
@@ -128,7 +128,7 @@ mod tests {
|
|
|
#[test]
|
|
|
fn check_bits() {
|
|
|
// Set bits 0-5 (6 bits total)
|
|
|
- let p = Possible(set_bits(6));
|
|
|
+ let p = Bits(set_bits(6));
|
|
|
|
|
|
for i in 0..6 {
|
|
|
let result = p.get(i);
|
|
@@ -139,19 +139,69 @@ mod tests {
|
|
|
}
|
|
|
|
|
|
pub type SudokuBoard = [u8; MAX_SIZE as usize];
|
|
|
-pub type SudokuPossible = [Possible; MAX_SIZE as usize];
|
|
|
+pub type Possible = [Bits; MAX_SIZE as usize];
|
|
|
+pub type SudokuPossible = [Bits; MAX_SIZE as usize];
|
|
|
+
|
|
|
+#[derive(Debug, Clone, Copy)]
|
|
|
+pub struct Board([u8; MAX_SIZE as usize]);
|
|
|
+#[derive(Debug, Clone, Copy)]
|
|
|
+pub struct BoardPossible([Bits; MAX_SIZE as usize]);
|
|
|
|
|
|
/*
|
|
|
I probably should keep board and possible separate from one another.
|
|
|
Possible is only used when solving the puzzles, and only used by the
|
|
|
logic solver. Not needed by brute-force.
|
|
|
+
|
|
|
+Ok, the problem is that the possible doesn't make any sense to be
|
|
|
+unlinked in any way from the board. I think they have to be together.
|
|
|
*/
|
|
|
|
|
|
+ /*
|
|
|
+#[derive(Debug, Clone, Copy)]
|
|
|
+pub struct SudokuPossible {
|
|
|
+ pub possible: [Possible; MAX_SIZE as usize];
|
|
|
+}
|
|
|
+*/
|
|
|
+
|
|
|
+impl BoardPossible {
|
|
|
+ /// Display the possibles.
|
|
|
+ /// This should be in the Possible struct, not here.
|
|
|
+ pub fn display(&self) {
|
|
|
+ for y in 0..WIDTH {
|
|
|
+ for x in 0..WIDTH {
|
|
|
+ // print!("p={:?}", self.possible[pos(x, y) as usize]);
|
|
|
+ let mut possible = String::new();
|
|
|
+
|
|
|
+ for p in self.0[pos(x, y) as usize].iter() {
|
|
|
+ // print!("{},", p);
|
|
|
+ possible += format!("{},", p).as_str();
|
|
|
+ }
|
|
|
+
|
|
|
+ // for i in 0..SIZE {
|
|
|
+ // let &pos = self.possible[pos(x, y) as usize];
|
|
|
+ print!("({},{}):", x, y);
|
|
|
+ // print!("{:20}", format!("{:?}", self.possible[pos(x, y) as usize]));
|
|
|
+ print!("{:9}", possible);
|
|
|
+ /*
|
|
|
+ if pos == 0 {
|
|
|
+ print!(" ");
|
|
|
+ } else {
|
|
|
+ print!("{}", pos);
|
|
|
+ }
|
|
|
+ */
|
|
|
+ // }
|
|
|
+ // print!(" ");
|
|
|
+ }
|
|
|
+ println!("");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
pub struct Sudoku {
|
|
|
- pub board: [u8; MAX_SIZE as usize],
|
|
|
- // pub possible: [HashSet<u8>; MAX_SIZE as usize],
|
|
|
- pub possible: [Possible; MAX_SIZE as usize],
|
|
|
+ pub board: [u8; MAX_SIZE as usize], // Board
|
|
|
+ pub possible: [Bits; MAX_SIZE as usize], // BoardPossible
|
|
|
}
|
|
|
|
|
|
/// Translate x,y to position in board.
|
|
@@ -183,7 +233,7 @@ let arr: [Vec<u32>; 10] = [(); 10].map(|_| Vec::with_capacity(100));
|
|
|
impl Sudoku {
|
|
|
pub fn new() -> Self {
|
|
|
// let b : HashSet<u8> = HashSet::from_iter(1..=9);
|
|
|
- let mut initial: Possible = Possible(set_bits(10));
|
|
|
+ let mut initial: Bits = Bits(set_bits(10));
|
|
|
initial.set(0, false);
|
|
|
|
|
|
let s = Sudoku {
|
|
@@ -194,13 +244,13 @@ impl Sudoku {
|
|
|
}
|
|
|
|
|
|
pub fn clear_possible(&mut self) {
|
|
|
- let mut initial = Possible(set_bits(10));
|
|
|
+ let mut initial = Bits(set_bits(10));
|
|
|
initial.set(0, false);
|
|
|
self.possible = [initial; MAX_SIZE as usize];
|
|
|
}
|
|
|
|
|
|
pub fn clear(&mut self) {
|
|
|
- let mut initial = Possible(set_bits(10));
|
|
|
+ let mut initial = Bits(set_bits(10));
|
|
|
initial.set(0, false);
|
|
|
|
|
|
self.board = [0; MAX_SIZE as usize];
|
|
@@ -486,7 +536,7 @@ impl Sudoku {
|
|
|
pub fn bruteforce_solver(&self) -> u16 {
|
|
|
let mut workset = Sudoku {
|
|
|
board: self.board,
|
|
|
- possible: [Possible(0); MAX_SIZE as usize],
|
|
|
+ possible: [Bits(0); MAX_SIZE as usize],
|
|
|
};
|
|
|
|
|
|
let mut total_solutions: u16 = 0;
|
|
@@ -670,7 +720,7 @@ impl Sudoku {
|
|
|
}
|
|
|
|
|
|
let mut g = Group::new();
|
|
|
- let mut values = Possible(0); // HashSet<u8> = HashSet::new();
|
|
|
+ let mut values = Bits(0); // HashSet<u8> = HashSet::new();
|
|
|
|
|
|
let mut group_process = |this: &mut Self, grp: &Group| {
|
|
|
// Collect all the possible values within the group.
|