|
@@ -21,32 +21,36 @@ use rand_chacha::ChaCha20Rng;
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
pub struct Possible(u16);
|
|
pub struct Possible(u16);
|
|
|
|
|
|
|
|
+/// Set bits number of bits to 1 (true)
|
|
pub const fn set_bits(bits: u8) -> u16 {
|
|
pub const fn set_bits(bits: u8) -> u16 {
|
|
(1 << (bits)) - 1
|
|
(1 << (bits)) - 1
|
|
}
|
|
}
|
|
|
|
|
|
impl Possible {
|
|
impl Possible {
|
|
|
|
+ /// clear all bits
|
|
pub fn clear(&mut self) {
|
|
pub fn clear(&mut self) {
|
|
self.0 = 0;
|
|
self.0 = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// set bit to state of value.
|
|
pub fn set(&mut self, bit: u8, value: bool) {
|
|
pub fn set(&mut self, bit: u8, value: bool) {
|
|
- // print!("{} set {}={}", self.0, bit, value);
|
|
|
|
- self.0.set_bit((bit - 1) as usize, value);
|
|
|
|
- // println!("{}", self.0);
|
|
|
|
|
|
+ self.0.set_bit(bit as usize, value);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// get state of bit.
|
|
pub fn get(&self, bit: u8) -> bool {
|
|
pub fn get(&self, bit: u8) -> bool {
|
|
- self.0.get_bit((bit - 1) as usize)
|
|
|
|
|
|
+ self.0.get_bit(bit as usize)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// set bits on, given number of bits initially to set.
|
|
pub fn set_bits(&mut self, bits: u8) {
|
|
pub fn set_bits(&mut self, bits: u8) {
|
|
self.0 = set_bits(bits);
|
|
self.0 = set_bits(bits);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// count number of bits set.
|
|
pub fn count_set(&self) -> u8 {
|
|
pub fn count_set(&self) -> u8 {
|
|
let mut count = 0;
|
|
let mut count = 0;
|
|
- for i in 1..u16::BIT_LENGTH {
|
|
|
|
|
|
+ for i in 0..u16::BIT_LENGTH {
|
|
if self.get(i as u8) {
|
|
if self.get(i as u8) {
|
|
count += 1;
|
|
count += 1;
|
|
}
|
|
}
|
|
@@ -73,11 +77,11 @@ impl<'a> Iterator for PossibleIterator<'a> {
|
|
type Item = u8;
|
|
type Item = u8;
|
|
|
|
|
|
fn next(&mut self) -> Option<u8> {
|
|
fn next(&mut self) -> Option<u8> {
|
|
- while (self.index <= u16::BIT_LENGTH as u8) && (!self.possible.get(self.index)) {
|
|
|
|
|
|
+ while (self.index < u16::BIT_LENGTH as u8) && (!self.possible.get(self.index)) {
|
|
self.index += 1;
|
|
self.index += 1;
|
|
// println!("index = {}", self.index);
|
|
// println!("index = {}", self.index);
|
|
}
|
|
}
|
|
- if self.index >= u16::BIT_LENGTH as u8 {
|
|
|
|
|
|
+ if self.index == u16::BIT_LENGTH as u8 {
|
|
None
|
|
None
|
|
} else {
|
|
} else {
|
|
self.index += 1;
|
|
self.index += 1;
|
|
@@ -121,7 +125,9 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
fn check_bits() {
|
|
fn check_bits() {
|
|
- let mut p = Possible(set_bits(5));
|
|
|
|
|
|
+ // Set bits 0-5 (6 bits total)
|
|
|
|
+ let p = Possible(set_bits(6));
|
|
|
|
+
|
|
for i in 0..6 {
|
|
for i in 0..6 {
|
|
let result = p.get(i);
|
|
let result = p.get(i);
|
|
assert_eq!(result, true);
|
|
assert_eq!(result, true);
|
|
@@ -166,7 +172,8 @@ let arr: [Vec<u32>; 10] = [(); 10].map(|_| Vec::with_capacity(100));
|
|
impl Sudoku {
|
|
impl Sudoku {
|
|
pub fn new() -> Self {
|
|
pub fn new() -> Self {
|
|
// let b : HashSet<u8> = HashSet::from_iter(1..=9);
|
|
// let b : HashSet<u8> = HashSet::from_iter(1..=9);
|
|
- let initial: Possible = Possible(set_bits(9));
|
|
|
|
|
|
+ let mut initial: Possible = Possible(set_bits(10));
|
|
|
|
+ initial.set(0, false);
|
|
|
|
|
|
let s = Sudoku {
|
|
let s = Sudoku {
|
|
board: [0; MAX_SIZE as usize],
|
|
board: [0; MAX_SIZE as usize],
|
|
@@ -176,7 +183,9 @@ impl Sudoku {
|
|
}
|
|
}
|
|
|
|
|
|
pub fn clear(&mut self) {
|
|
pub fn clear(&mut self) {
|
|
- let initial = Possible(set_bits(9));
|
|
|
|
|
|
+ let mut initial = Possible(set_bits(10));
|
|
|
|
+ initial.set(0, false);
|
|
|
|
+
|
|
self.board = [0; MAX_SIZE as usize];
|
|
self.board = [0; MAX_SIZE as usize];
|
|
self.possible = [initial; MAX_SIZE as usize];
|
|
self.possible = [initial; MAX_SIZE as usize];
|
|
}
|
|
}
|
|
@@ -506,7 +515,7 @@ impl Sudoku {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn solve(&mut self) -> bool {
|
|
|
|
|
|
+ pub fn solve(&mut self, debug: bool) -> bool {
|
|
// Pass 1: Look for singles in the possible sets.
|
|
// Pass 1: Look for singles in the possible sets.
|
|
let mut found_something = false;
|
|
let mut found_something = false;
|
|
|
|
|
|
@@ -515,7 +524,9 @@ impl Sudoku {
|
|
// Get the value
|
|
// Get the value
|
|
let value = self.possible[i as usize].iter().next().unwrap();
|
|
let value = self.possible[i as usize].iter().next().unwrap();
|
|
// Found one!
|
|
// Found one!
|
|
- println!("Set1 {:?} to {}", xy(i), value);
|
|
|
|
|
|
+ if debug {
|
|
|
|
+ println!("Set1 {:?} to {}", xy(i), value);
|
|
|
|
+ }
|
|
self.set(xy(i).0, xy(i).1, value);
|
|
self.set(xy(i).0, xy(i).1, value);
|
|
found_something = true;
|
|
found_something = true;
|
|
}
|
|
}
|
|
@@ -555,7 +566,9 @@ impl Sudoku {
|
|
if count == 1 {
|
|
if count == 1 {
|
|
// don't need this, it was v!
|
|
// don't need this, it was v!
|
|
// let value = this.possible[pos as usize].iter().next().cloned().unwrap();
|
|
// let value = this.possible[pos as usize].iter().next().cloned().unwrap();
|
|
- println!("Set2 {:?} to {}", xy(pos), v);
|
|
|
|
|
|
+ if debug {
|
|
|
|
+ println!("Set2 {:?} to {}", xy(pos), v);
|
|
|
|
+ }
|
|
this.set(xy(pos).0, xy(pos).1, v);
|
|
this.set(xy(pos).0, xy(pos).1, v);
|
|
found_something = true;
|
|
found_something = true;
|
|
}
|
|
}
|
|
@@ -579,7 +592,9 @@ impl Sudoku {
|
|
return found_something;
|
|
return found_something;
|
|
}
|
|
}
|
|
|
|
|
|
- println!("Looking for pairs...");
|
|
|
|
|
|
+ if debug {
|
|
|
|
+ println!("Looking for pairs...");
|
|
|
|
+ }
|
|
// PAIR processing.
|
|
// PAIR processing.
|
|
for i in 0..WIDTH {
|
|
for i in 0..WIDTH {
|
|
g.for_iter(i);
|
|
g.for_iter(i);
|
|
@@ -692,15 +707,17 @@ impl Sudoku {
|
|
}
|
|
}
|
|
|
|
|
|
if pair_removed {
|
|
if pair_removed {
|
|
- println!(
|
|
|
|
- "Pair found! {} {}: {} {:?} and {} {:?} !",
|
|
|
|
- gidx,
|
|
|
|
- fidx,
|
|
|
|
- gpos,
|
|
|
|
- xy(gpos),
|
|
|
|
- fpos,
|
|
|
|
- xy(fpos)
|
|
|
|
- );
|
|
|
|
|
|
+ if debug {
|
|
|
|
+ println!(
|
|
|
|
+ "Pair found! {} {}: {} {:?} and {} {:?} !",
|
|
|
|
+ gidx,
|
|
|
|
+ fidx,
|
|
|
|
+ gpos,
|
|
|
|
+ xy(gpos),
|
|
|
|
+ fpos,
|
|
|
|
+ xy(fpos)
|
|
|
|
+ );
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|