|  | @@ -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.
 |