Browse Source

Move GenBits to Vec<bool>.

The iterator only shows indexes of bits set.
Checking for zero (nothing set) use .count_set() instead.
Steve Thielemann 1 month ago
parent
commit
c109afb181
3 changed files with 366 additions and 171 deletions
  1. 207 4
      sudoku/src/bits.rs
  2. 49 100
      sudoku/src/group.rs
  3. 110 67
      sudoku/src/sudoku.rs

+ 207 - 4
sudoku/src/bits.rs

@@ -1,16 +1,218 @@
-// Use bitfields instead of HashSets.
-
 /*
 /*
 Or MAYBE, just use Vec<bool> ?!
 Or MAYBE, just use Vec<bool> ?!
 While that would use more memory, it would certainly be faster!
 While that would use more memory, it would certainly be faster!
 Is saving a few bytes (these days) worth it, really?
 Is saving a few bytes (these days) worth it, really?
 
 
-The iterator would be interesting...
+The iterator would ... already be written for Vec<T>. :P
+(Buuut, not quite. I only want true values...)
+
+fn main() {
+    let vector = vec![true, false, false, true];
+
+    for z in vector.iter().enumerate().filter(|x| *x.1) {
+        println!("{:?}", z);
+    }
+    for z in vector.iter().enumerate().filter(|x| *x.1) {
+        println!("{:?}", z);
+    }
+}
+
+This returns (0, true), (3, true)
+
+fn main() {
+    let vector = vec![true, false, false, true];
+
+    let d : Vec<usize> = vector.iter().enumerate().filter(|x| *x.1).map(|x| x.0).collect();
+    println!("{:?}", &d);
+}
+
+This returns (0,3) !  This is what I was looking for!
+I'd rather have an iterator (like I have below), but I might
+have to compromise here.
+
+    let d = vector.iter().enumerate().filter(|x| *x.1).map(|x| x.0);
+    for dv in d {
+        println!(" {}", dv);
+    }
+
+There we go, map returns iterator. :D
+Enumerate creates (index, value),
+filter finds "true" items,
+map returns iterator (with index)!
 
 
 And we could handle any crazy size as well... :O
 And we could handle any crazy size as well... :O
 
 
  */
  */
 
 
+use std::ops::RangeBounds;
+// use std::iter::{Map, Filter, Enumerate};
+
+#[derive(Clone, Debug)]
+pub struct GenBits(pub Vec<bool>);
+
+impl GenBits {
+    pub fn new(size: usize) -> Self {
+        GenBits(vec![false; size])
+    }
+
+    pub fn clear(&mut self) {
+        for i in 0..self.0.len() {
+            self.0[i] = false;
+        }
+    }
+    pub fn set(&mut self, bit: usize, state: bool) {
+        self.0[bit] = state;
+    }
+
+    pub fn get(&self, bit: usize) -> bool {
+        self.0[bit]
+    }
+
+    pub fn set_bits<R: RangeBounds<usize> + IntoIterator<Item = usize>>(&mut self, bits: R) {
+        for i in bits {
+            self.0[i as usize] = true;
+        }
+    }
+
+    pub fn count_set(&self) -> usize {
+        self.0.iter().filter(|&x| *x).count()
+    }
+
+    // https://depth-first.com/articles/2020/06/22/returning-rust-iterators/
+
+    #[deprecated="Use iter() instead."]
+    /// Returns the indexes of items that are true
+    pub fn indexes(&self) -> impl Iterator<Item = usize> + '_ {
+        self.0.iter().enumerate().filter(|x| *x.1).map(|x| x.0)
+    }
+
+    /// The "default" iterator for GenBits returns this.
+    pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
+        self.0.iter().enumerate().filter(|x| *x.1).map(|x| x.0)
+    }
+
+    /* 
+    pub fn iter(&self) -> std::slice::Iter<'_, bool> {
+        self.0.iter()
+    }
+    */
+
+    /// Display bits that are set.
+    /// +1 is added to the display, so it matches the cell values (1..N)
+    pub fn display(&self) -> String {
+        self.0.iter()
+            .enumerate()
+            .filter(|x| *x.1)
+            .map(|x| x.0)
+            .map(|i| (i+1).to_string())
+            // .map(|i| i.to_string())
+            .collect::<Vec<_>>().join(",")
+    }
+
+}
+
+impl PartialEq for GenBits {
+    fn eq(&self, other: &Self) -> bool {
+        if self.0.len() != other.0.len() {
+            return false;
+        }
+        for i in 0..self.0.len() {
+            if self.0[i] != other.0[i] {
+                return false;
+            }
+        }
+        true
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    // use crate::sudoku::*;
+    use crate::bits::*;
+
+    #[test]
+    fn check_u16() {
+        const size:usize = 9;
+        let mut p = GenBits::new(size);
+
+        p.clear();
+
+        for i in 0..9 {
+            let mut result = p.get(i);
+            assert_eq!(result, false);
+            p.set(i, true);
+            result = p.get(i);
+            assert_eq!(result, true);
+        }
+
+        p = GenBits::new(size);
+        p.set(3, true);
+        p.set(5, true);
+        p.set(6, true);
+        assert_eq!(3, p.count_set());
+        let values: Vec<usize> = p.iter().collect();
+        assert_eq!(values, vec!(3, 5, 6));
+        assert_eq!(3, p.count_set());
+        p.set(0, true);
+        assert_eq!(4, p.count_set());
+
+        p = GenBits::new(size);
+        p.set_bits(0..6);
+
+        for i in 0..6 {
+            let result = p.get(i);
+            assert_eq!(result, true);
+        }
+        assert_eq!(p.get(6), false);
+    }
+
+    #[test]
+    fn check_u32() {
+        const size:usize = 29;
+        let mut p = GenBits::new(size);
+
+        p.clear();
+
+        for i in 0..29 {
+            let mut result = p.get(i);
+            assert_eq!(result, false);
+            p.set(i, true);
+            result = p.get(i);
+            assert_eq!(result, true);
+        }
+
+        p = GenBits::new(size);
+        p.set(13, true);
+        p.set(15, true);
+        p.set(26, true);
+        assert_eq!(3, p.count_set());
+        let values: Vec<usize> = p.iter().collect();
+        assert_eq!(values, vec!(13, 15, 26));
+        assert_eq!(3, p.count_set());
+        p.set(0, true);
+        assert_eq!(4, p.count_set());
+
+        p = GenBits::new(size);
+        p.set_bits(10..26);
+
+        for i in 10..26 {
+            let result = p.get(i);
+            assert_eq!(result, true);
+        }
+        assert_eq!(p.get(9), false);
+        assert_eq!(p.get(27), false);
+    }
+}
+
+
+/*
+    // -> Map<Filter<Enumerate<std::slice::Iter<'_, bool>>>>
+    pub fn indexes(&self) -> std::slice::Iter<usize>  {
+        self.data.iter().enumerate().filter(|x| *x.1).map(|x| x.0)
+    }
+*/
+
+/*
 use bit_field::BitField;
 use bit_field::BitField;
 
 
 // If I wanted to do 4x4 or 5x5, I would need more bits. (u32).
 // If I wanted to do 4x4 or 5x5, I would need more bits. (u32).
@@ -183,5 +385,6 @@ mod tests {
         assert_eq!(p.get(9), false);
         assert_eq!(p.get(9), false);
         assert_eq!(p.get(27), false);
         assert_eq!(p.get(27), false);
     }
     }
-
 }
 }
+
+*/

+ 49 - 100
sudoku/src/group.rs

@@ -1,11 +1,3 @@
-/*
-New code -
-    AnyGroup
-        Handles any size puzzles.
-
-The old code below only handles 3x3 puzzles only!
- */
-
 // use std::fmt;
 // use std::fmt;
 use strum::EnumIter;
 use strum::EnumIter;
 use strum::IntoEnumIterator;
 use strum::IntoEnumIterator;
@@ -18,27 +10,14 @@ pub enum Groups {
     Cell,
     Cell,
 }
 }
 
 
-/*
- impl fmt::Display for Groups {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{:?}", self)
-        // or, alternatively:
-        // fmt::Debug::fmt(self, f)
-    }
-}
-*/
-
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub struct AnyGroup {
 pub struct AnyGroup {
     pub size: u8,
     pub size: u8,
     pub width: u8,
     pub width: u8,
     pub max_index: usize,
     pub max_index: usize,
     pub groups: [Vec<usize>; 3],
     pub groups: [Vec<usize>; 3],
-    /*
-    pub row: Vec<usize>,
-    pub column: Vec<usize>,
-    pub cell: Vec<usize>,
-    */
+    pub row_cell: Vec<usize>,
+    pub col_cell: Vec<usize>,
 }
 }
 
 
 /// Find the number of digits needed to display given number.
 /// Find the number of digits needed to display given number.
@@ -61,6 +40,8 @@ impl AnyGroup {
             width: board_size * board_size,
             width: board_size * board_size,
             max_index: size,
             max_index: size,
             groups: [vec![0; size], vec![0; size], vec![0; size]],
             groups: [vec![0; size], vec![0; size], vec![0; size]],
+            row_cell: vec![0; size],
+            col_cell: vec![0; size],
             /*
             /*
             row: vec![0; b_width * b_width],
             row: vec![0; b_width * b_width],
             column: vec![0; size],
             column: vec![0; size],
@@ -71,21 +52,60 @@ impl AnyGroup {
         g
         g
     }
     }
 
 
+    fn calculate(&mut self) {
+        let size = self.size;
+        for y in 0..self.width {
+            self.row_cell[y as usize] = y as usize / size as usize;
+            self.col_cell[y as usize] = (y as usize/ size as usize) * size as usize;
+
+            for x in 0..self.width {
+                let index = self.pos(x,y);
+                // x as usize + y as usize * self.width as usize;
+                
+                self.groups[Groups::Row as usize][index] = self.pos(x, y);
+                self.groups[Groups::Column as usize][index] = self.pos(y, x);
+
+                // self.row[index] = self.pos(x, y);
+                // self.column[index] = self.pos(y, x);
+
+                let x_off = x / size;
+                let y_off = y / size;
+                let x_mod = x % size;
+                let y_mod = y % size;
+                // x is correct:
+                //    x_mod + y_mod * self.size;
+                // y is correct:
+                //    x_off + y_off * self.size
+                self.groups[Groups::Cell as usize][index] =
+                    self.pos(x_mod + y_mod * size, x_off + y_off * size);
+
+            }
+        }
+    }
+
+    #[must_use]
+    #[inline]
+    /// Convert (X,Y) to index.
     pub fn pos(&self, x: u8, y: u8) -> usize {
     pub fn pos(&self, x: u8, y: u8) -> usize {
         x as usize + y as usize * self.width as usize
         x as usize + y as usize * self.width as usize
     }
     }
 
 
+    #[must_use]
+    #[inline]
+    /// Convert index to (X,Y).
     pub fn xy(&self, index: usize) -> (u8, u8) {
     pub fn xy(&self, index: usize) -> (u8, u8) {
         let width = self.width as usize;
         let width = self.width as usize;
         ((index % width) as u8, (index / width) as u8)
         ((index % width) as u8, (index / width) as u8)
     }
     }
 
 
+    /// Indexes for that Group (Row,Column,Cell)
     pub fn group(&self, g: Groups, row: u8) -> &[usize] {
     pub fn group(&self, g: Groups, row: u8) -> &[usize] {
         let width = self.width as usize;
         let width = self.width as usize;
         let start = row as usize * width;
         let start = row as usize * width;
         &self.groups[g as usize][start..start + width]
         &self.groups[g as usize][start..start + width]
     }
     }
 
 
+    /// Indexes for that row
     pub fn row(&self, row: u8) -> &[usize] {
     pub fn row(&self, row: u8) -> &[usize] {
         // return slice of row:
         // return slice of row:
         let width = self.width as usize;
         let width = self.width as usize;
@@ -93,6 +113,7 @@ impl AnyGroup {
         &self.groups[Groups::Row as usize][start..start + width]
         &self.groups[Groups::Row as usize][start..start + width]
     }
     }
 
 
+    /// Indexes for that column
     pub fn column(&self, column: u8) -> &[usize] {
     pub fn column(&self, column: u8) -> &[usize] {
         // return slice of row:
         // return slice of row:
         let width = self.width as usize;
         let width = self.width as usize;
@@ -100,6 +121,7 @@ impl AnyGroup {
         &self.groups[Groups::Column as usize][start..start + width]
         &self.groups[Groups::Column as usize][start..start + width]
     }
     }
 
 
+    // Indexes for that cell.
     pub fn cell(&self, cell: u8) -> &[usize] {
     pub fn cell(&self, cell: u8) -> &[usize] {
         // return slice of cell:
         // return slice of cell:
         let width = self.width as usize;
         let width = self.width as usize;
@@ -113,11 +135,14 @@ impl AnyGroup {
         (x / self.size) + (y / self.size) * self.size
         (x / self.size) + (y / self.size) * self.size
     }
     }
 
 
+    /*
+    #[deprecated="Use xy() instead"]
     #[must_use]
     #[must_use]
     /// Convert index to x,y offsets.
     /// Convert index to x,y offsets.
     pub fn cell_offset(&self, idx:u8) -> (u8,u8) {
     pub fn cell_offset(&self, idx:u8) -> (u8,u8) {
         (idx % self.size, idx / self.size)
         (idx % self.size, idx / self.size)
     }
     }
+    */
     
     
     #[must_use]
     #[must_use]
     /// Which index for given cell and (x,y)?
     /// Which index for given cell and (x,y)?
@@ -144,40 +169,9 @@ impl AnyGroup {
         result + (y * self.width + x) as usize
         result + (y * self.width + x) as usize
     }
     }
 
 
-    pub fn calculate(&mut self) {
-        for y in 0..self.width {
-            for x in 0..self.width {
-                let index = x as usize + y as usize * self.width as usize;
-                self.groups[Groups::Row as usize][index] = self.pos(x, y);
-                self.groups[Groups::Column as usize][index] = self.pos(y, x);
-
-                // self.row[index] = self.pos(x, y);
-                // self.column[index] = self.pos(y, x);
-
-                let x_off = x / self.size;
-                let y_off = y / self.size;
-                let x_mod = x % self.size;
-                let y_mod = y % self.size;
-                // x is correct:
-                //    x_mod + y_mod * self.size;
-                // y is correct:
-                //    x_off + y_off * self.size
-                self.groups[Groups::Cell as usize][index] =
-                    self.pos(x_mod + y_mod * self.size, x_off + y_off * self.size);
-
-                /* self.cell[index] = self.pos(
-                    x_mod + y_mod * self.size,
-                    x_off + y_off * self.size, // x_mod + x_off * self.size,
-                                               // y_off
-                );
-                */
-            }
-        }
-    }
-
     // Possibly update this so it shows +1 on x and y
     // Possibly update this so it shows +1 on x and y
     // to match actual positions (rather then starting at 0).
     // to match actual positions (rather then starting at 0).
-
+    /// display Group
     pub fn display(&self) {
     pub fn display(&self) {
         let max_index_size = find_number_width(self.width as usize * self.width as usize);
         let max_index_size = find_number_width(self.width as usize * self.width as usize);
         let max_pos_size = find_number_width(self.width as usize);
         let max_pos_size = find_number_width(self.width as usize);
@@ -214,51 +208,6 @@ impl AnyGroup {
                 printer(i, r);
                 printer(i, r);
             }
             }
         }
         }
-        /*
-        println!("rows:");
-        // println!("{:?}", self.row);
-        for i in 0..self.width {
-            let r = self.row(i);
-            /*
-            print!("[{:2}]: ", i);
-            for j in r {
-                let xy = self.xy(*j);
-                print!("{0:1$}({2:2},{3:2}) ", j, max_index_size, xy.0, xy.1);
-            }
-            println!("");
-            */
-            printer(i, r);
-        }
-        println!("columns:");
-        // println!("{:?}", self.column);
-        for i in 0..self.width {
-            let r = self.column(i);
-            /*
-            print!("[{:2}]: ", i);
-            for j in r {
-                let xy = self.xy(*j);
-                print!("{0:1$}({2:2},{3:2}) ", j, max_index_size, xy.0, xy.1);
-            }
-            println!("");
-            */
-            printer(i, r);
-        }
-
-        println!("cells:");
-        // println!("{:?}", self.cell);
-        for i in 0..self.width {
-            let r = self.cell(i);
-            /*
-            print!("[{:2}]: ", i);
-            for j in r {
-                let xy = self.xy(*j);
-                print!("{0:1$}({2:2},{3:2}) ", j, max_index_size, xy.0, xy.1);
-            }
-            println!("");
-            */
-            printer(i, r);
-        }
-        */
     }
     }
 }
 }
 
 

+ 110 - 67
sudoku/src/sudoku.rs

@@ -461,32 +461,29 @@ pub struct AnyPossible {
     pub size: u8,
     pub size: u8,
     pub width: u8,
     pub width: u8,
     pub max_index: usize,
     pub max_index: usize,
-    pub possible: Vec<GenBits<u32>>,
+    pub possible: Vec<GenBits>,
 }
 }
 
 
 impl AnyPossible {
 impl AnyPossible {
     pub fn new(board_size: u8) -> Self {
     pub fn new(board_size: u8) -> Self {
-        let mut initial = GenBits::<u32>(0);
-        let width = board_size * board_size;
-        initial.set_bits(0..width);
+        let width = board_size as usize * board_size as usize;
+        let mut initial = GenBits::new(width);
+        // let width = board_size * board_size;
+        initial.set_bits(0..width as usize);
 
 
         Self {
         Self {
             size: board_size,
             size: board_size,
-            width: width,
-            max_index: width as usize * width as usize,
-            possible: vec![initial; width as usize * width as usize],
+            width: width as u8,
+            max_index: width * width,
+            possible: vec![initial; width * width],
         }
         }
     }
     }
 
 
     pub fn clear(&mut self) {
     pub fn clear(&mut self) {
-        let mut initial = GenBits::<u32>(0);
+        let mut initial = GenBits::new(self.width as usize);
         // let width = self.size * self.size;
         // let width = self.size * self.size;
-        initial.set_bits(0..self.width);
-
+        initial.set_bits(0..self.width as usize);
         self.possible.fill(initial);
         self.possible.fill(initial);
-
-        // self.possible = vec![initial; self.max_index];
-        // width as usize * width as usize];
     }
     }
 
 
     pub fn copy(&mut self, copy_from: &Self) {
     pub fn copy(&mut self, copy_from: &Self) {
@@ -497,7 +494,7 @@ impl AnyPossible {
             self.size
             self.size
         );
         );
         for i in 0..self.max_index {
         for i in 0..self.max_index {
-            self.possible[i] = copy_from.possible[i];
+            self.possible[i] = copy_from.possible[i].clone();
         }
         }
     }
     }
 
 
@@ -514,7 +511,7 @@ impl AnyPossible {
             index,
             index,
             self.max_index
             self.max_index
         );
         );
-        let changed = self.possible[index].get(value-1) != state;
+        let changed = self.possible[index].get(value - 1) != state;
         self.possible[index].set(value - 1, state);
         self.possible[index].set(value - 1, state);
         changed
         changed
     }
     }
@@ -578,12 +575,12 @@ impl AnyPossible {
     }
     }
 
 
     #[must_use]
     #[must_use]
-    pub fn find_pairs(&mut self, cellgroup: &[usize]) -> (Vec<(Vec<u8>, Vec<u8>)>, bool) {
+    pub fn find_pairs(&mut self, cellgroup: &[usize]) -> (Vec<(Vec<usize>, Vec<u8>)>, bool) {
         // result[value] = indexes where it is located?
         // result[value] = indexes where it is located?
         // Step 1: find values, and their position(s).
         // Step 1: find values, and their position(s).
 
 
-        let initial = GenBits::<u32>(0);
-        let mut result: Vec<GenBits<u32>> = vec![initial; self.width as usize];
+        let initial = GenBits::new(self.width as usize);
+        let mut result: Vec<GenBits> = vec![initial; self.width as usize];
 
 
         // let cellgroup = self.group.group(Groups::Cell, cell_index);
         // let cellgroup = self.group.group(Groups::Cell, cell_index);
 
 
@@ -602,21 +599,21 @@ impl AnyPossible {
 
 
         // Step 2: pair them up, and if complete, fixup possible (if needed).
         // Step 2: pair them up, and if complete, fixup possible (if needed).
 
 
-        let zero_bits = GenBits::<u32>(0);
+        let zero_bits = GenBits::new(self.width as usize);
         let width = self.width;
         let width = self.width;
         let mut possibles_updated: bool = false;
         let mut possibles_updated: bool = false;
-        let mut pairs: Vec<(Vec<u8>, Vec<u8>)> = vec![];
+        let mut pairs: Vec<(Vec<usize>, Vec<u8>)> = vec![];
 
 
         'outer: for idx in 0..width - 1 {
         'outer: for idx in 0..width - 1 {
             // pos_found contains the positions.
             // pos_found contains the positions.
-            let pos_found = result[idx as usize];
-            if pos_found == zero_bits {
+            let pos_found = &result[idx as usize];
+            if pos_found.count_set() == 0 {
                 continue;
                 continue;
             }
             }
             if idx > 0 {
             if idx > 0 {
                 // Check previous for matches - already checked...
                 // Check previous for matches - already checked...
                 for check in 0..idx {
                 for check in 0..idx {
-                    if pos_found == result[check as usize] {
+                    if *pos_found == result[check as usize] {
                         continue 'outer;
                         continue 'outer;
                     }
                     }
                 }
                 }
@@ -637,7 +634,7 @@ impl AnyPossible {
 
 
             if count != 1 {
             if count != 1 {
                 for look in idx + 1..width {
                 for look in idx + 1..width {
-                    if result[look as usize] == pos_found {
+                    if result[look as usize] == *pos_found {
                         matches += 1;
                         matches += 1;
                         pos.push(look);
                         pos.push(look);
                     }
                     }
@@ -647,13 +644,13 @@ impl AnyPossible {
             if matches == count {
             if matches == count {
                 // Ok! We found a pair (or triple, or quad, or ...)
                 // Ok! We found a pair (or triple, or quad, or ...)
                 // Build new possible
                 // Build new possible
-                let mut new_possible = zero_bits;
+                let mut new_possible = zero_bits.clone();
                 for p in &pos {
                 for p in &pos {
                     new_possible.set(*p as usize, true);
                     new_possible.set(*p as usize, true);
                 }
                 }
-                let mut index_pos: Vec<u8> = Vec::<u8>::new();
+                let mut index_pos = Vec::<usize>::new();
 
 
-                for p in pos_found.iter() {
+                for p in pos_found.indexes() {
                     index_pos.push(p);
                     index_pos.push(p);
                     if self.possible[cellgroup[p as usize]] != new_possible {
                     if self.possible[cellgroup[p as usize]] != new_possible {
                         // println!("Update pos {} with {:?}", p, new_possible);
                         // println!("Update pos {} with {:?}", p, new_possible);
@@ -665,7 +662,7 @@ impl AnyPossible {
                         );
                         );
                         */
                         */
                         possibles_updated = true;
                         possibles_updated = true;
-                        self.possible[cellgroup[p as usize]] = new_possible;
+                        self.possible[cellgroup[p as usize]] = new_possible.clone();
                         // println!("Updated!");
                         // println!("Updated!");
                     }
                     }
                 }
                 }
@@ -678,18 +675,20 @@ impl AnyPossible {
 
 
     #[must_use]
     #[must_use]
     /// Find positions where each value is possible.
     /// Find positions where each value is possible.
-    pub fn find_value_pos(&self) -> Vec<GenBits<u32>> {
-        let zero = GenBits::<u32>(0);
-        let mut result = vec![zero; self.size as usize];
-        
-        for index in 0..self.size {
+    /// - Vec index is value
+    /// - GenBits are the positions it is found.
+    pub fn find_value_pos(&self) -> Vec<GenBits> {
+        let zero = GenBits::new(self.width as usize);
+        let mut result = vec![zero.clone(); self.width as usize];
+
+        for index in 0..self.width {
             if self.possible[index as usize] == zero {
             if self.possible[index as usize] == zero {
                 continue;
                 continue;
             }
             }
 
 
             // Ok, there's some value there.
             // Ok, there's some value there.
-            // Would it be better to use the iterator here?
-            for v in self.possible[index as usize].iter() {
+            // Would it be better to use the iterator here? Yes, I think so.
+            for v in self.possible[index as usize].indexes() {
                 result[v as usize].set(index as usize, true);
                 result[v as usize].set(index as usize, true);
             }
             }
 
 
@@ -746,15 +745,16 @@ pub struct AnySolver {
     pub possible: AnyPossible,
     pub possible: AnyPossible,
     pub group: AnyGroup,
     pub group: AnyGroup,
     // Is this value set in the given cell?
     // Is this value set in the given cell?
-    pub cell_poss: Vec<GenBits<u32>>,
+    pub cell_poss: Vec<GenBits>,
 }
 }
 
 
 impl AnySolver {
 impl AnySolver {
     /// Construct new solver from given board size. (3,4,5)
     /// Construct new solver from given board size. (3,4,5)
     pub fn new(board_size: u8) -> Self {
     pub fn new(board_size: u8) -> Self {
-        let mut default_poss = GenBits::<u32>(0);
         let width: u8 = board_size * board_size;
         let width: u8 = board_size * board_size;
-        default_poss.set_bits(0..width);
+        let mut default_poss = GenBits::new(width as usize);
+
+        default_poss.set_bits(0..width as usize);
 
 
         let mut s = Self {
         let mut s = Self {
             board: AnyBoard::new(board_size),
             board: AnyBoard::new(board_size),
@@ -768,8 +768,8 @@ impl AnySolver {
 
 
     /// Construct new solver from given board.
     /// Construct new solver from given board.
     pub fn new_from(initial_board: &AnyBoard) -> Self {
     pub fn new_from(initial_board: &AnyBoard) -> Self {
-        let mut default_poss = GenBits::<u32>(0);
-        default_poss.set_bits(0..initial_board.width);
+        let mut default_poss = GenBits::new(initial_board.width as usize);
+        default_poss.set_bits(0..initial_board.width as usize);
 
 
         let mut s = AnySolver {
         let mut s = AnySolver {
             board: initial_board.clone(),
             board: initial_board.clone(),
@@ -828,7 +828,7 @@ impl AnySolver {
             self.possible.set(*g, val, false);
             self.possible.set(*g, val, false);
         }
         }
         let idx = self.possible.pos(x, y);
         let idx = self.possible.pos(x, y);
-        self.possible.possible[idx] = GenBits::<u32>(0);
+        self.possible.possible[idx] = GenBits::new(self.board.width as usize);
         self.board.board[idx] = value;
         self.board.board[idx] = value;
 
 
         //
         //
@@ -884,14 +884,12 @@ impl AnySolver {
         }
         }
 
 
         // What values are possible in which rows/columns and cells?
         // What values are possible in which rows/columns and cells?
-        
+
         // Scan rows/columns
         // Scan rows/columns
         for cell in 0..width {
         for cell in 0..width {
             let cell_info = self.group.group(Groups::Cell, cell);
             let cell_info = self.group.group(Groups::Cell, cell);
 
 
-            for row in 0..size {
-
-            }
+            for row in 0..size {}
         }
         }
     }
     }
 
 
@@ -899,14 +897,54 @@ impl AnySolver {
     /// Finalize move on the board.
     /// Finalize move on the board.
     /// - This uses the cell index last modified, so we have fewer
     /// - This uses the cell index last modified, so we have fewer
     ///   cells to check here. (2 * size) cells.
     ///   cells to check here. (2 * size) cells.
-    #[deprecated]
     pub fn finalize_cell(&mut self, cell_index: u8) {
     pub fn finalize_cell(&mut self, cell_index: u8) {
         let width = self.board.width;
         let width = self.board.width;
         let size = self.board.size;
         let size = self.board.size;
-        let mut update: bool = false;
+        // let mut update: bool = false;
+
+        // use width, not size. ;)
+        let mut cell_has_value = vec![false; width as usize];
+
+        let mut cell_update = vec![false; width as usize];
+        cell_update[cell_index as usize] = true;
+
+        let values = self.possible.find_value_pos();
+
+        for (value, positions) in values.iter().enumerate() {
+            if positions.count_set() == 0 {
+                // No positions, skip it.
+                continue;
+            }
+
+            // reset
+            cell_has_value.fill(false);
 
 
+            for p in positions.iter() {
+                cell_has_value[p as usize] = true;
+            }
+
+            println!("Value {} : Pos {:?}", value, cell_has_value);
+
+            // cell_has_value gives me the indexes that contain value.
+            // I need to process cell rows/columns...
+            // Start with processing one (cell row), and refactor. (like always)
+
+            // cells on left (because cells have the constraints).
+            for cell in (0..size).map(|x| x * size) {
+                // let c = self.group.cell(cell);
+                let mut c = Vec::<&[usize]>::new();
+                for row in 0..size {
+                    c.push(self.group.cell(cell + row));
+                }
+
+                // rows go the entire width of the game...
+                for row in 0..width {}
+            }
+        }
+        /*
         let _pairs = self.possible
         let _pairs = self.possible
             .find_pairs(self.group.group(Groups::Cell, cell_index));
             .find_pairs(self.group.group(Groups::Cell, cell_index));
+        */
 
 
         // println!("Finalize Cell Pairs: {:?}", self.possible.find_pairs(self.group.group(Groups::Cell, index)));
         // println!("Finalize Cell Pairs: {:?}", self.possible.find_pairs(self.group.group(Groups::Cell, index)));
 
 
@@ -954,13 +992,13 @@ impl AnySolver {
         I probably need some helpers to give me a row/column of a given position... as well.
         I probably need some helpers to give me a row/column of a given position... as well.
         row/column iterators ?
         row/column iterators ?
 
 
-        1.)  
-        In a given cell's column/row, if a number is possible in that cell's column/row, remove it from the other cell's row/column.  
+        1.)
+        In a given cell's column/row, if a number is possible in that cell's column/row, remove it from the other cell's row/column.
         (Must be there, so remove it.)
         (Must be there, so remove it.)
         (3,7), (3,8), (3,9) remove 2.
         (3,7), (3,8), (3,9) remove 2.
 
 
         2.)
         2.)
-        In a given cell's column/row, if a number isn't possible in the same column/row in the other cells 
+        In a given cell's column/row, if a number isn't possible in the same column/row in the other cells
           -- remove that number as possible from that cell's other row/columns.
           -- remove that number as possible from that cell's other row/columns.
 
 
         When updating the possibles - track which cells changed (so we can check/recheck just those).
         When updating the possibles - track which cells changed (so we can check/recheck just those).
@@ -969,7 +1007,7 @@ impl AnySolver {
         When allocating the blocks, possibly use the max value (size) -- this should keep the allocated blocks
         When allocating the blocks, possibly use the max value (size) -- this should keep the allocated blocks
         the same (hopefully keep reusing the same size block of memory over and over)
         the same (hopefully keep reusing the same size block of memory over and over)
         -- or allocate it once and just reuse/init the same block over and over ? (reduce allocation/deallocations)
         -- or allocate it once and just reuse/init the same block over and over ? (reduce allocation/deallocations)
-        
+
         Also the reverse should be possible:
         Also the reverse should be possible:
         ╔═══╦═══╦═══╗
         ╔═══╦═══╦═══╗
         ║T  ║   ║   ║
         ║T  ║   ║   ║
@@ -1002,12 +1040,17 @@ impl AnySolver {
 
 
         // Ranges are consumed.
         // Ranges are consumed.
 
 
+        // This looks like it does what I'm doing somewhere else!
+        // TODO:
+        // TOFIX:
+        // See: AnyPossible's find_value_pos!
+
         // Check columns - (of given cell) for logical removes (see logic_test for example)
         // Check columns - (of given cell) for logical removes (see logic_test for example)
         for value in 0..width {
         for value in 0..width {
             // Find what columns value is allowed. (in which cells).
             // Find what columns value is allowed. (in which cells).
             // Is this value needed in any of the cells?
             // Is this value needed in any of the cells?
-            let mut found = GenBits::<u32>(0);
-            let mut all_cells = found;
+            let mut found = GenBits::new(width as usize);
+            let mut all_cells = found.clone();
 
 
             for ci in (top_cell..width).step_by(size as usize) {
             for ci in (top_cell..width).step_by(size as usize) {
                 all_cells.set(ci as usize, true);
                 all_cells.set(ci as usize, true);
@@ -1016,12 +1059,12 @@ impl AnySolver {
                 }
                 }
             }
             }
 
 
-            if found == GenBits::<u32>(0) {
+            if found.count_set() == 0 {
                 // Not possible anywhere, so skip to next value.
                 // Not possible anywhere, so skip to next value.
                 continue;
                 continue;
             }
             }
 
 
-            println!("Value {} {:?} is needed {:?}", value + 1, all_cells, found);
+            // println!("Value {} {:?} is needed {:?}", value + 1, all_cells, found);
 
 
             for x in x_range.clone() {
             for x in x_range.clone() {
                 for y in 0..width {
                 for y in 0..width {
@@ -1072,11 +1115,11 @@ impl AnySolver {
 
 
         self.possible.clear();
         self.possible.clear();
         // reset cell possible
         // reset cell possible
-        let mut default_poss = GenBits::<u32>(0);
-        default_poss.set_bits(0..self.board.width);
+        let mut default_poss = GenBits::new(self.board.width as usize);
+        default_poss.set_bits(0..self.board.width as usize);
 
 
         for x in 0..self.board.width {
         for x in 0..self.board.width {
-            self.cell_poss[x as usize] = default_poss;
+            self.cell_poss[x as usize] = default_poss.clone();
         }
         }
 
 
         for y in 0..self.board.width {
         for y in 0..self.board.width {
@@ -1130,11 +1173,11 @@ impl AnySolver {
         self.possible.clear();
         self.possible.clear();
 
 
         // reset cell possible
         // reset cell possible
-        let mut default_poss = GenBits::<u32>(0);
-        default_poss.set_bits(0..self.board.width);
+        let mut default_poss = GenBits::new(self.board.width as usize);
+        default_poss.set_bits(0..self.board.width as usize);
 
 
         for x in 0..self.board.width {
         for x in 0..self.board.width {
-            self.cell_poss[x as usize] = default_poss;
+            self.cell_poss[x as usize] = default_poss.clone();
         }
         }
 
 
         for y in 0..self.board.width {
         for y in 0..self.board.width {
@@ -1208,7 +1251,7 @@ impl AnySolver {
                 available.reserve(width as usize);
                 available.reserve(width as usize);
 
 
                 for t in self.possible.possible[idx].iter() {
                 for t in self.possible.possible[idx].iter() {
-                    available.push(t + 1);
+                    available.push((t + 1) as u8);
                 }
                 }
                 if available.len() == 0 {
                 if available.len() == 0 {
                     return false;
                     return false;
@@ -1235,7 +1278,7 @@ impl AnySolver {
                     self.possible.copy(&backup.possible);
                     self.possible.copy(&backup.possible);
 
 
                     for i in 0..backup.cell_poss.len() {
                     for i in 0..backup.cell_poss.len() {
-                        self.cell_poss[i] = backup.cell_poss[i];
+                        self.cell_poss[i] = backup.cell_poss[i].clone();
                     }
                     }
                     // self.cell_poss.copy( backup.cell_poss);
                     // self.cell_poss.copy( backup.cell_poss);
                 }
                 }
@@ -1316,7 +1359,7 @@ impl AnySolver {
                     let value = self.possible.possible[i].iter().next().unwrap() + 1;
                     let value = self.possible.possible[i].iter().next().unwrap() + 1;
                     let pos = self.board.xy(i);
                     let pos = self.board.xy(i);
                     // println!("SET {}({},{})={}", i, pos.0 + 1, pos.1 + 1, value);
                     // println!("SET {}({},{})={}", i, pos.0 + 1, pos.1 + 1, value);
-                    self.set(pos.0, pos.1, value, true);
+                    self.set(pos.0, pos.1, value as u8, true);
                     found_something = true;
                     found_something = true;
                 }
                 }
             }
             }
@@ -1345,7 +1388,7 @@ impl AnySolver {
             pass2_again = false;
             pass2_again = false;
 
 
             // let mut values = Bits(0); // HashSet<u8> = HashSet::new();
             // let mut values = Bits(0); // HashSet<u8> = HashSet::new();
-            let mut values = GenBits::<u32>(0);
+            let mut values = GenBits::new(self.board.width as usize);
 
 
             let mut group_process = |this: &mut Self, grp: &[usize]| {
             let mut group_process = |this: &mut Self, grp: &[usize]| {
                 // Collect all the possible values within the group.
                 // Collect all the possible values within the group.
@@ -1386,7 +1429,7 @@ impl AnySolver {
                         let xy = this.board.xy(pos);
                         let xy = this.board.xy(pos);
                         // this.possible.display();
                         // this.possible.display();
                         // this.board.display();
                         // this.board.display();
-                        this.set(xy.0, xy.1, v + 1, true);
+                        this.set(xy.0, xy.1, (v + 1) as u8, true);
                         // println!("SET {} ({},{}) = {}", pos, xy.0 + 1, xy.1 + 1, v+1);
                         // println!("SET {} ({},{}) = {}", pos, xy.0 + 1, xy.1 + 1, v+1);
 
 
                         found_something = true;
                         found_something = true;
@@ -1857,7 +1900,7 @@ mod tests {
         println!("--- logic_test ---");
         println!("--- logic_test ---");
     }
     }
 
 
-    #[ignore]
+    #[ignore = "Possible doesn't process these correctly. No, not yet!"]
     #[test]
     #[test]
     fn try_this_out() {
     fn try_this_out() {
         let mut board = AnyBoard::new(3);
         let mut board = AnyBoard::new(3);