Sfoglia il codice sorgente

Removed dead code (9x9 only).

Still need make/remove for making puzzle.
Steve Thielemann 4 mesi fa
parent
commit
6ab9bf1df2
6 ha cambiato i file con 342 aggiunte e 1835 eliminazioni
  1. 10 28
      src/main.rs
  2. 0 113
      sudoku/src/bits.rs
  3. 0 454
      sudoku/src/group.rs
  4. 13 28
      sudoku/src/ksudoku.rs
  5. 1 1
      sudoku/src/lib.rs
  6. 318 1211
      sudoku/src/sudoku.rs

+ 10 - 28
src/main.rs

@@ -20,7 +20,7 @@ fn main() {
             .action(ArgAction::SetTrue),
         )
         .arg(arg!(-b --brute ... "Brute-force solver").action(ArgAction::SetTrue))
-        .arg(arg!(-d --debug ... "Debug output").action(ArgAction::SetTrue))
+        // .arg(arg!(-d --debug ... "Debug output").action(ArgAction::SetTrue))
         .arg(
             arg!(-s --size <SIZE>... "Puzzle size")
                 .required(false)
@@ -29,14 +29,16 @@ fn main() {
         )
         .get_matches();
 
+    /* 
     let mut debug: bool = false;
     if args.get_flag("debug") {
         debug = true;
     }
+    */
 
     if args.get_flag("make") {
         let size: u8 = *args.get_one::<u8>("size").unwrap();
-        let mut s = AnyBoard::new(size);
+        let mut _s = AnyBoard::new(size);
 
         /*
         s.make();
@@ -120,15 +122,17 @@ fn main() {
         } else {
             let mut solver = AnySolver::new_from(&s);
 
-            while solver.solve_logic() {};
-
-            if solver.board.complete() {
+            if solver.solve_logic() {
                 println!("Solution:");
                 solver.board.display();
+                if solver.board != solution {
+                    println!("The solution doesn't match the one from the file:");
+                    solution.display();
+                }
             } else {
                 println!("This is as far as logic could get us:");
                 solver.board.display();
-                println!("Using brute-force.");
+                println!("Guessing required, using brute-force.");
                 let (count, boards) = solver.board.brute_force_solver(2);
                 if count == 1 {
                     boards[0].display();
@@ -140,28 +144,6 @@ fn main() {
                     println!("Found {} solutions.", count);
                 }
             }
-            /*
-            while s.solve(debug) {
-                println!("Try it again...");
-                if debug {
-                    s.display();
-                    s.display_possible();
-                }
-            }
-
-            if !s.puzzle_complete() {
-                if !debug {
-                    println!("This is as far we could get with logic alone:");
-                    s.display();
-                }
-                println!("Trying bruteforce.");
-                println!("Bruteforce solutions: {}", s.bruteforce_solver());
-            } else {
-                if !debug {
-                    s.display();
-                }
-            }
-            */
         }
     }
 }

+ 0 - 113
sudoku/src/bits.rs

@@ -76,124 +76,11 @@ impl<'a, T: Integer + BitField> Iterator for GenBitsIterator<'a, T> {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct Bits(pub u16);
-
-/// Set bits number of bits to 1 (true)
-pub const fn set_bits(bits: u8) -> u16 {
-    (1 << (bits)) - 1
-}
-
-impl Bits {
-    /// clear all bits
-    pub fn clear(&mut self) {
-        self.0 = 0;
-    }
-
-    /// set bit to state of value.
-    pub fn set(&mut self, bit: u8, value: bool) {
-        self.0.set_bit(bit as usize, value);
-    }
-
-    /// get state of bit.
-    pub fn get(&self, bit: u8) -> bool {
-        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) {
-        self.0 = set_bits(bits);
-    }
-
-    /// count number of bits set.
-    pub fn count_set(&self) -> u8 {
-        let mut count = 0;
-        for i in 0..u16::BIT_LENGTH {
-            if self.get(i as u8) {
-                count += 1;
-            }
-        }
-        count
-    }
-}
-
-pub struct BitsIterator<'a> {
-    pub possible: &'a Bits,
-    pub index: u8,
-}
-
-impl Bits {
-    pub fn iter(&self) -> BitsIterator {
-        BitsIterator {
-            possible: self,
-            index: 1,
-        }
-    }
-}
-
-impl<'a> Iterator for BitsIterator<'a> {
-    type Item = u8;
-
-    fn next(&mut self) -> Option<u8> {
-        while (self.index < u16::BIT_LENGTH as u8) && (!self.possible.get(self.index)) {
-            self.index += 1;
-            // println!("index = {}", self.index);
-        }
-        if self.index == u16::BIT_LENGTH as u8 {
-            None
-        } else {
-            self.index += 1;
-            Some(self.index - 1)
-        }
-    }
-}
-
 #[cfg(test)]
 mod tests {
     // use crate::sudoku::*;
     use crate::bits::*;
 
-    #[test]
-    fn check_possible_bitset() {
-        let mut p = Bits(0);
-
-        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);
-        }
-    }
-
-    #[test]
-    fn check_possible_iter() {
-        let mut p = Bits(0);
-        p.set(3, true);
-        p.set(5, true);
-        p.set(6, true);
-        assert_eq!(3, p.count_set());
-        let values: Vec<u8> = 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());
-    }
-
-    #[test]
-    fn check_bits() {
-        // Set bits 0-5 (6 bits total)
-        let p = Bits(set_bits(6));
-
-        for i in 0..6 {
-            let result = p.get(i);
-            assert_eq!(result, true);
-        }
-        assert_eq!(p.get(6), false);
-    }
-
     #[test]
     fn check_u16() {
         let mut p = GenBits::<u16>(0);

+ 0 - 454
sudoku/src/group.rs

@@ -1,8 +1,3 @@
-use std::fmt;
-
-// load sudoku
-use crate::*;
-
 /*
 New code -
     AnyGroup
@@ -175,418 +170,11 @@ impl AnyGroup {
     }
 }
 
-/*
-  ___  _     _    ____          _
- / _ \| | __| |  / ___|___   __| | ___
-| | | | |/ _` | | |   / _ \ / _` |/ _ \
-| |_| | | (_| | | |__| (_) | (_| |  __/
- \___/|_|\__,_|  \____\___/ \__,_|\___|
-
-Static tables for 3x3 boards only...
- */
-
-/// Width of the sudoku board.
-const WIDTH: u8 = 9;
-// /// Size (width * height) of the board.
-// const MAX_SIZE: u8 = 81;
-
-// #[derive(Debug)]
-/// Define a Group of sudoku positions.
-/// This defines rows, columns, and cells for analysis.
-#[derive(PartialEq)]
-pub struct Group(pub [usize; WIDTH as usize]);
-
-/*
-pub struct Group {
-    pub items: [u8; WIDTH as usize],
-}
- */
-
-/// Group of positions for rows.
-const GROUP_ROW: [Group; 9] = [
-    Group([
-        pos1(1, 1),
-        pos1(2, 1),
-        pos1(3, 1),
-        pos1(4, 1),
-        pos1(5, 1),
-        pos1(6, 1),
-        pos1(7, 1),
-        pos1(8, 1),
-        pos1(9, 1),
-    ]),
-    Group([
-        pos1(1, 2),
-        pos1(2, 2),
-        pos1(3, 2),
-        pos1(4, 2),
-        pos1(5, 2),
-        pos1(6, 2),
-        pos1(7, 2),
-        pos1(8, 2),
-        pos1(9, 2),
-    ]),
-    Group([
-        pos1(1, 3),
-        pos1(2, 3),
-        pos1(3, 3),
-        pos1(4, 3),
-        pos1(5, 3),
-        pos1(6, 3),
-        pos1(7, 3),
-        pos1(8, 3),
-        pos1(9, 3),
-    ]),
-    Group([
-        pos1(1, 4),
-        pos1(2, 4),
-        pos1(3, 4),
-        pos1(4, 4),
-        pos1(5, 4),
-        pos1(6, 4),
-        pos1(7, 4),
-        pos1(8, 4),
-        pos1(9, 4),
-    ]),
-    Group([
-        pos1(1, 5),
-        pos1(2, 5),
-        pos1(3, 5),
-        pos1(4, 5),
-        pos1(5, 5),
-        pos1(6, 5),
-        pos1(7, 5),
-        pos1(8, 5),
-        pos1(9, 5),
-    ]),
-    Group([
-        pos1(1, 6),
-        pos1(2, 6),
-        pos1(3, 6),
-        pos1(4, 6),
-        pos1(5, 6),
-        pos1(6, 6),
-        pos1(7, 6),
-        pos1(8, 6),
-        pos1(9, 6),
-    ]),
-    Group([
-        pos1(1, 7),
-        pos1(2, 7),
-        pos1(3, 7),
-        pos1(4, 7),
-        pos1(5, 7),
-        pos1(6, 7),
-        pos1(7, 7),
-        pos1(8, 7),
-        pos1(9, 7),
-    ]),
-    Group([
-        pos1(1, 8),
-        pos1(2, 8),
-        pos1(3, 8),
-        pos1(4, 8),
-        pos1(5, 8),
-        pos1(6, 8),
-        pos1(7, 8),
-        pos1(8, 8),
-        pos1(9, 8),
-    ]),
-    Group([
-        pos1(1, 9),
-        pos1(2, 9),
-        pos1(3, 9),
-        pos1(4, 9),
-        pos1(5, 9),
-        pos1(6, 9),
-        pos1(7, 9),
-        pos1(8, 9),
-        pos1(9, 9),
-    ]),
-];
-
-/// Group of positions for columns.
-const GROUP_COLUMN: [Group; 9] = [
-    Group([
-        pos1(1, 1),
-        pos1(1, 2),
-        pos1(1, 3),
-        pos1(1, 4),
-        pos1(1, 5),
-        pos1(1, 6),
-        pos1(1, 7),
-        pos1(1, 8),
-        pos1(1, 9),
-    ]),
-    Group([
-        pos1(2, 1),
-        pos1(2, 2),
-        pos1(2, 3),
-        pos1(2, 4),
-        pos1(2, 5),
-        pos1(2, 6),
-        pos1(2, 7),
-        pos1(2, 8),
-        pos1(2, 9),
-    ]),
-    Group([
-        pos1(3, 1),
-        pos1(3, 2),
-        pos1(3, 3),
-        pos1(3, 4),
-        pos1(3, 5),
-        pos1(3, 6),
-        pos1(3, 7),
-        pos1(3, 8),
-        pos1(3, 9),
-    ]),
-    Group([
-        pos1(4, 1),
-        pos1(4, 2),
-        pos1(4, 3),
-        pos1(4, 4),
-        pos1(4, 5),
-        pos1(4, 6),
-        pos1(4, 7),
-        pos1(4, 8),
-        pos1(4, 9),
-    ]),
-    Group([
-        pos1(5, 1),
-        pos1(5, 2),
-        pos1(5, 3),
-        pos1(5, 4),
-        pos1(5, 5),
-        pos1(5, 6),
-        pos1(5, 7),
-        pos1(5, 8),
-        pos1(5, 9),
-    ]),
-    Group([
-        pos1(6, 1),
-        pos1(6, 2),
-        pos1(6, 3),
-        pos1(6, 4),
-        pos1(6, 5),
-        pos1(6, 6),
-        pos1(6, 7),
-        pos1(6, 8),
-        pos1(6, 9),
-    ]),
-    Group([
-        pos1(7, 1),
-        pos1(7, 2),
-        pos1(7, 3),
-        pos1(7, 4),
-        pos1(7, 5),
-        pos1(7, 6),
-        pos1(7, 7),
-        pos1(7, 8),
-        pos1(7, 9),
-    ]),
-    Group([
-        pos1(8, 1),
-        pos1(8, 2),
-        pos1(8, 3),
-        pos1(8, 4),
-        pos1(8, 5),
-        pos1(8, 6),
-        pos1(8, 7),
-        pos1(8, 8),
-        pos1(8, 9),
-    ]),
-    Group([
-        pos1(9, 1),
-        pos1(9, 2),
-        pos1(9, 3),
-        pos1(9, 4),
-        pos1(9, 5),
-        pos1(9, 6),
-        pos1(9, 7),
-        pos1(9, 8),
-        pos1(9, 9),
-    ]),
-];
-
-/// Group of positions for cells (3x3 grid).
-const GROUP_CELL: [Group; 9] = [
-    Group([
-        pos1(1, 1),
-        pos1(2, 1),
-        pos1(3, 1),
-        pos1(1, 2),
-        pos1(2, 2),
-        pos1(3, 2),
-        pos1(1, 3),
-        pos1(2, 3),
-        pos1(3, 3),
-    ]),
-    Group([
-        pos1(4, 1),
-        pos1(5, 1),
-        pos1(6, 1),
-        pos1(4, 2),
-        pos1(5, 2),
-        pos1(6, 2),
-        pos1(4, 3),
-        pos1(5, 3),
-        pos1(6, 3),
-    ]),
-    Group([
-        pos1(7, 1),
-        pos1(8, 1),
-        pos1(9, 1),
-        pos1(7, 2),
-        pos1(8, 2),
-        pos1(9, 2),
-        pos1(7, 3),
-        pos1(8, 3),
-        pos1(9, 3),
-    ]),
-    Group([
-        pos1(1, 4),
-        pos1(2, 4),
-        pos1(3, 4),
-        pos1(1, 5),
-        pos1(2, 5),
-        pos1(3, 5),
-        pos1(1, 6),
-        pos1(2, 6),
-        pos1(3, 6),
-    ]),
-    Group([
-        pos1(4, 4),
-        pos1(5, 4),
-        pos1(6, 4),
-        pos1(4, 5),
-        pos1(5, 5),
-        pos1(6, 5),
-        pos1(4, 6),
-        pos1(5, 6),
-        pos1(6, 6),
-    ]),
-    Group([
-        pos1(7, 4),
-        pos1(8, 4),
-        pos1(9, 4),
-        pos1(7, 5),
-        pos1(8, 5),
-        pos1(9, 5),
-        pos1(7, 6),
-        pos1(8, 6),
-        pos1(9, 6),
-    ]),
-    Group([
-        pos1(1, 7),
-        pos1(2, 7),
-        pos1(3, 7),
-        pos1(1, 8),
-        pos1(2, 8),
-        pos1(3, 8),
-        pos1(1, 9),
-        pos1(2, 9),
-        pos1(3, 9),
-    ]),
-    Group([
-        pos1(4, 7),
-        pos1(5, 7),
-        pos1(6, 7),
-        pos1(4, 8),
-        pos1(5, 8),
-        pos1(6, 8),
-        pos1(4, 9),
-        pos1(5, 9),
-        pos1(6, 9),
-    ]),
-    Group([
-        pos1(7, 7),
-        pos1(8, 7),
-        pos1(9, 7),
-        pos1(7, 8),
-        pos1(8, 8),
-        pos1(9, 8),
-        pos1(7, 9),
-        pos1(8, 9),
-        pos1(9, 9),
-    ]),
-];
-
-impl fmt::Debug for Group {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if f.alternate() {
-            write!(f, "Group {{ {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}] }}",
-                self.0[0], xy(self.0[0]).0, xy(self.0[0]).1,
-                self.0[1], xy(self.0[1]).0, xy(self.0[1]).1,
-                self.0[2], xy(self.0[2]).0, xy(self.0[2]).1,
-                self.0[3], xy(self.0[3]).0, xy(self.0[3]).1,
-                self.0[4], xy(self.0[4]).0, xy(self.0[4]).1,
-                self.0[5], xy(self.0[5]).0, xy(self.0[5]).1,
-                self.0[6], xy(self.0[6]).0, xy(self.0[6]).1,
-                self.0[7], xy(self.0[7]).0, xy(self.0[7]).1,
-                self.0[8], xy(self.0[8]).0, xy(self.0[8]).1,
-            )
-        } else {
-            f.debug_struct("Group").field("items", &self).finish()
-        }
-    }
-}
-
-pub fn for_column(x: u8) -> &'static Group {
-    &GROUP_COLUMN[x as usize]
-}
-
-pub fn for_row(y: u8) -> &'static Group {
-    &GROUP_ROW[y as usize]
-}
-
-pub fn for_cell(i: u8) -> &'static Group {
-    &GROUP_CELL[i as usize]
-}
-
-/// Which cell contains this x,y?
-pub fn which_cell(x: u8, y: u8) -> u8 {
-    (x / 3) + (y / 3) * 3
-}
 
 #[cfg(test)]
 mod tests {
     use crate::group::*;
 
-    #[test]
-    fn check_columns() {
-        let mut g = Group::new();
-
-        for i in 0..9 {
-            // println!("Index={}", i);
-            g.for_column(i, 1);
-            let new_g = for_column(i);
-            assert_eq!(g, *new_g);
-        }
-    }
-
-    #[test]
-    fn check_rows() {
-        let mut g = Group::new();
-
-        for i in 0..9 {
-            // println!("Index={}", i);
-            g.for_row(1, i);
-            let new_g = for_row(i);
-            assert_eq!(g, *new_g);
-        }
-    }
-
-    #[test]
-    fn check_cells() {
-        let mut g = Group::new();
-        for i in 0..9 {
-            // println!("Index={}", i);
-            g.for_block((i % 3) * 3, (i / 3) * 3);
-            let new_g = for_cell(i);
-            assert_eq!(g, *new_g);
-        }
-    }
-
     #[test]
     fn check_dynamic() {
         // Verify that each index (0..max_index) is defined in each group.
@@ -692,45 +280,3 @@ mod tests {
         }
     }
 }
-
-impl Group {
-    pub fn new() -> Self {
-        Group([0; WIDTH as usize])
-    }
-
-    pub fn for_column(&mut self, x: u8, _y: u8) {
-        for y in 0..WIDTH {
-            self.0[y as usize] = pos(x, y);
-        }
-    }
-    pub fn for_row(&mut self, _x: u8, y: u8) {
-        for x in 0..WIDTH {
-            self.0[x as usize] = pos(x, y);
-        }
-    }
-    pub fn for_block(&mut self, x: u8, y: u8) {
-        // Find starting block positions
-        let sb_x = x - (x % 3);
-        let sb_y = y - (y % 3);
-        for i in 0..WIDTH {
-            let ix = i % 3;
-            let iy = i / 3;
-            // println!("i = {}, sb.x = {} sb.y = {}, ix = {} iy = {}", i, sb_x, sb_y, ix, iy);
-            self.0[i as usize] = pos(sb_x + ix, sb_y + iy);
-        }
-    }
-
-    pub fn for_iter(&mut self, i: u8) {
-        let sb_x = (i % 3) * 3;
-        let sb_y = (i / 3) * 3;
-        self.for_block(sb_x, sb_y);
-    }
-
-    pub fn display(&self) {
-        for i in 0..WIDTH {
-            let v = self.0[i as usize];
-            print!("{} [{},{}] ", v, xy(v).0, xy(v).1);
-        }
-        println!("");
-    }
-}

+ 13 - 28
sudoku/src/ksudoku.rs

@@ -8,21 +8,6 @@ use xml::reader::{EventReader, XmlEvent};
 use xml::writer::XmlEvent as WrXmlEvent;
 use xml::EmitterConfig;
 
-/*
-#[derive(Debug, Clone)]
-struct UnsupportedGroup {
-    message: String,
-}
-
-impl fmt::Display for UnsupportedGroup {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Unsupported group: {}", self.message)
-    }
-}
-
-impl error::Error for UnsupportedGroup {}
-*/
-
 /*
 What I want from load_ksudoku:
 
@@ -34,13 +19,7 @@ What I want from load_ksudoku:
 I get values (the puzzle), I also need solution.
 
 Having order will allow me to use AnyBoard::new(order) and load it up.
-
-Currently, it loads, and will fail if it isn't Plain, sudoku, 9.
-I'm not sure what future ksudoku puzzles I want to support, so I'd like to
-have that as flexible as possible.
-
-save_ksudoku, would need to save those fields as well...
- */
+*/
 
 #[derive(Debug)]
 pub struct Ksudoku {
@@ -207,10 +186,16 @@ mod tests {
 
     #[test]
     fn load_puzzles() {
+        let mut testfile = test_files_path();
+        testfile.push("missing");
+
+        let result = load_ksudoku(testfile);
+        assert!(result.is_err());
+
         let mut testfile = test_files_path();
         testfile.push("9-puzzle");
 
-        let mut result = load_ksudoku(testfile);
+        let result = load_ksudoku(testfile);
         assert!(result.is_ok());
         let result = result.unwrap();
         assert!(result.puzzle_type == "sudoku");
@@ -218,7 +203,7 @@ mod tests {
 
         let size = (result.order as f64).sqrt() as u8;
         let mut board = AnyBoard::new(size);
-        let mut load = board.load_from_tld('b', '_', &result.puzzle);
+        let load = board.load_from_tld('b', '_', &result.puzzle);
         assert!(load.is_ok());
 
         // Ok, puzzle is loaded!
@@ -241,7 +226,7 @@ mod tests {
         let mut testfile = test_files_path();
         testfile.push("16-puzzle");
 
-        let mut result = load_ksudoku(testfile);
+        let result = load_ksudoku(testfile);
         assert!(result.is_ok());
         let result = result.unwrap();
         assert!(result.puzzle_type == "sudoku");
@@ -249,7 +234,7 @@ mod tests {
 
         let size = (result.order as f64).sqrt() as u8;
         let mut board = AnyBoard::new(size);
-        let mut load = board.load_from_tld('b', '_', &result.puzzle);
+        let load = board.load_from_tld('b', '_', &result.puzzle);
         assert!(load.is_ok());
 
         // Ok, puzzle is loaded!
@@ -280,7 +265,7 @@ mod tests {
         let mut testfile = test_files_path();
         testfile.push("25-puzzle");
 
-        let mut result = load_ksudoku(testfile);
+        let result = load_ksudoku(testfile);
         assert!(result.is_ok());
         let result = result.unwrap();
         assert!(result.puzzle_type == "sudoku");
@@ -288,7 +273,7 @@ mod tests {
 
         let size = (result.order as f64).sqrt() as u8;
         let mut board = AnyBoard::new(size);
-        let mut load = board.load_from_tld('b', '_', &result.puzzle);
+        let load = board.load_from_tld('b', '_', &result.puzzle);
         assert!(load.is_ok());
 
         // Ok, puzzle is loaded!

+ 1 - 1
sudoku/src/lib.rs

@@ -4,4 +4,4 @@ pub mod sudoku;
 pub mod bits;
 
 // use crate::group::*;
-use crate::sudoku::*;
+// use crate::sudoku::*;

+ 318 - 1211
sudoku/src/sudoku.rs

@@ -5,15 +5,9 @@ use crate::group::*;
 // use std::collections::HashSet;
 use std::string::String;
 
-const SIZE: u8 = 3;
-/// Width of the sudoku board.
-const WIDTH: u8 = SIZE * SIZE;
-/// Size (width * height) of the board.
-const MAX_SIZE: u8 = WIDTH * WIDTH; // 81;
-
 extern crate rand_chacha;
 // use rand::prelude::*;
-use rand::distributions::{Distribution, Uniform};
+// use rand::distributions::{Distribution, Uniform};
 use rand::seq::SliceRandom;
 use rand_chacha::rand_core::SeedableRng;
 use rand_chacha::ChaCha20Rng;
@@ -22,81 +16,6 @@ use rand_chacha::ChaCha20Rng;
 use std::error;
 use std::fmt;
 
-// Used bo calculate_possible to return the solutions.
-pub type SudokuBoard = [u8; 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]);
-
-impl Board {
-    pub fn new() -> Self {
-        let s = Self {
-            0: [0; MAX_SIZE as usize],
-        };
-        s
-    }
-
-    pub fn clear(&mut self) {
-        self.0 = [0; MAX_SIZE as usize];
-    }
-
-    pub fn set(&mut self, x: u8, y: u8, value: u8) {
-        self.0[pos(x, y) as usize] = value;
-    }
-
-    pub fn get(&mut self, x: u8, y: u8) -> u8 {
-        self.0[pos(x, y) as usize]
-    }
-
-    /// Load puzzle from a string.
-    /// Note, we load from (top,left) going down, to (bottom,left) by columns.
-    pub fn load_from_tld(&mut self, start_ch: char, blank: char, s: &str) {
-        self.clear();
-        let mut x: u8 = 0;
-        let mut y: u8 = 0;
-
-        for ch in s.chars() {
-            if ch != blank {
-                self.set(x, y, (ch as u8 - start_ch as u8) + 1);
-            }
-            y += 1;
-            if y >= WIDTH {
-                y = 0;
-                x += 1;
-            }
-        }
-    }
-
-    /// Save puzzle to a string.
-    /// Note, we load from (top,left) going down, to (bottom,left) by columns.
-
-    pub fn save_to_tld(&mut self, start_ch: char, blank: char) -> String {
-        let mut result = String::new();
-        result.reserve(MAX_SIZE as usize);
-        let start_ch = (start_ch as u8 - 1) as char;
-        let mut x: u8 = 0;
-        let mut y: u8 = 0;
-        for _i in 0..MAX_SIZE {
-            if self.0[pos(x, y) as usize] == 0 {
-                result.push(blank);
-            } else {
-                result.push((start_ch as u8 + self.0[pos(x, y) as usize]) as char);
-            }
-            y += 1;
-            if y >= WIDTH {
-                y = 0;
-                x += 1;
-            }
-        }
-        result
-    }
-}
-
 #[derive(Debug, Clone)]
 struct GameLoadError {
     message: String,
@@ -916,7 +835,6 @@ impl AnySolver {
                 // - Record that we did something.
                 pass1 = true;
                 pass1_again = true;
-                found_something = false;
             }
         }
         pass1
@@ -999,7 +917,7 @@ impl AnySolver {
 
             if found_something == true {
                 // Ok, pass 2 found something.
-                pass2 = true;                
+                pass2 = true;
                 found_something = false;
                 pass2_again = true;
                 // continue;
@@ -1009,344 +927,354 @@ impl AnySolver {
     }
 
     /// Solve by logic alone.
-    /// - Returns true when something was added to board.
-    /// - Call solve until it returns false.
+    /// - Returns true if solved.
     /// - It might not be solved (if guessing is required).
     pub fn solve_logic(&mut self) -> bool {
         // self.reset_possible(); // destroys anything pass3 accomplishes ...
 
         // self.board.display();
         // self.possible.display();
-        let mut result = true;
-        // Pass 1: Look for singles in the possible sets.
-        while result {
-            result = self.logic_pass1();
-            println!("Pass1");
-        }
 
-        let mut result2 = true;
-        while result2 {
-            result2 = self.logic_pass2();
-            println!("Pass2");
-        }
+        let mut found_more = true;
 
-        result || result2
-        /*
-        // Pass 2: Is the same as Pass 1!
-        // We just look in groups, instead of all the indexes.
+        while found_more {
+            found_more = false;
 
-        let mut found_something = false;
-        let mut pass1 = false;
+            let mut result1 = true;
+            // Pass 1: Look for singles in the possible sets.
+            while result1 {
+                result1 = self.logic_pass1();
+                if result1 {
+                    println!("Pass1");
+                };
+            }
 
-        // Repeat pass 1 until all have been found.
-        let mut pass1_again = true;
+            let mut result2 = true;
+            while result2 {
+                result2 = self.logic_pass2();
+                if result2 {
+                    println!("Pass2");
+                    found_more = true;
+                };
+            }
 
-        let width = self.group.width;
-        let grp = self.group.clone();
-        let mut pass2 = false;
+            /*
+            // Pass 2: Is the same as Pass 1!
+            // We just look in groups, instead of all the indexes.
 
-        while pass1_again {
-            // Pass 1 - look for singles.
+            let mut found_something = false;
+            let mut pass1 = false;
 
-            for i in 0..self.possible.max_index {
-                if self.board.board[i] != 0 {
-                    // Skip, if position already filled.
-                    continue;
-                }
+            // Repeat pass 1 until all have been found.
+            let mut pass1_again = true;
 
-                if self.possible.possible[i].count_set() == 1 {
-                    // Get value
-                    let value = self.possible.possible[i].iter().next().unwrap() + 1;
-                    let pos = self.board.xy(i);
-                    // println!("SET {}({},{})={}", i, pos.0 + 1, pos.1 + 1, value);
-                    self.set(pos.0, pos.1, value);
-                    found_something = true;
-                }
-            }
+            let width = self.group.width;
+            let grp = self.group.clone();
+            let mut pass2 = false;
 
-            if found_something {
-                // We found something this pass.
-                // - set pass1 to true (pass 1 found something)
-                // - reset found_something so we can try again.
-                pass1 = true;
-                found_something = false;
-                continue;
-            } else {
-                // Nothing found with this run of pass 1.
+            while pass1_again {
+                // Pass 1 - look for singles.
 
-                // Pass 2 - Look for singles within the groups.
+                for i in 0..self.possible.max_index {
+                    if self.board.board[i] != 0 {
+                        // Skip, if position already filled.
+                        continue;
+                    }
 
-                // Are we done?
-                /*
-                if self.board.complete() {
-                    return false;
+                    if self.possible.possible[i].count_set() == 1 {
+                        // Get value
+                        let value = self.possible.possible[i].iter().next().unwrap() + 1;
+                        let pos = self.board.xy(i);
+                        // println!("SET {}({},{})={}", i, pos.0 + 1, pos.1 + 1, value);
+                        self.set(pos.0, pos.1, value);
+                        found_something = true;
+                    }
                 }
-                // We're getting stuck in pass 2 ...
-                // not anymore.  ;)
-                println!("Pass 2:");
-                self.board.display();
 
-                */
-
-                found_something = false;
+                if found_something {
+                    // We found something this pass.
+                    // - set pass1 to true (pass 1 found something)
+                    // - reset found_something so we can try again.
+                    pass1 = true;
+                    found_something = false;
+                    continue;
+                } else {
+                    // Nothing found with this run of pass 1.
 
-                // let mut values = Bits(0); // HashSet<u8> = HashSet::new();
-                let mut values = GenBits::<u32>(0);
+                    // Pass 2 - Look for singles within the groups.
 
-                let mut group_process = |this: &mut Self, grp: &[usize]| {
-                    // Collect all the possible values within the group.
-                    values.clear();
-                    for gidx in 0..width {
-                        // println!("possible: {:?}", this.possible[grp.items[gidx as usize] as usize]);
-                        for v in this.possible.possible[grp[gidx as usize]].iter() {
-                            values.set(v as usize, true);
-                        }
-                        // values.extend(this.possible[grp.0[gidx as usize] as usize]);
-                        // println!("now     : {:?}", this.possible[grp.items[gidx as usize] as usize]);
+                    // Are we done?
+                    /*
+                    if self.board.complete() {
+                        return false;
                     }
+                    // We're getting stuck in pass 2 ...
+                    // not anymore.  ;)
+                    println!("Pass 2:");
+                    self.board.display();
 
-                    // println!("values {:?}", values);
+                    */
 
-                    // Now, check for singles.
-                    for v in values.iter() {
-                        // println!("Check Value: {}", v);
+                    found_something = false;
 
-                        let mut count = 0;
-                        let mut pos = 0;
+                    // let mut values = Bits(0); // HashSet<u8> = HashSet::new();
+                    let mut values = GenBits::<u32>(0);
 
+                    let mut group_process = |this: &mut Self, grp: &[usize]| {
+                        // Collect all the possible values within the group.
+                        values.clear();
                         for gidx in 0..width {
-                            if this.possible.possible[grp[gidx as usize]].get(v as usize) {
-                                // if this.possible[grp.0[gidx as usize] as usize].contains(&v) {
-                                count += 1;
-                                pos = grp[gidx as usize];
-                                if count > 1 {
-                                    break;
-                                } else {
-                                    // print!(" IDX {} POS {} ", gidx, pos);
-                                }
+                            // println!("possible: {:?}", this.possible[grp.items[gidx as usize] as usize]);
+                            for v in this.possible.possible[grp[gidx as usize]].iter() {
+                                values.set(v as usize, true);
                             }
+                            // values.extend(this.possible[grp.0[gidx as usize] as usize]);
+                            // println!("now     : {:?}", this.possible[grp.items[gidx as usize] as usize]);
                         }
-                        if count == 1 {
-                            // don't need this, it was v!
-                            // let value = this.possible[pos as usize].iter().next().cloned().unwrap();
-                            let xy = this.board.xy(pos);
-                            // this.possible.display();
-                            // this.board.display();
-                            this.set(xy.0, xy.1, v + 1);
-                            // println!("SET {} ({},{}) = {}", pos, xy.0 + 1, xy.1 + 1, v+1);
-
-                            found_something = true;
-                        }
-                    }
-                };
-
-                // Change to 0..WIDTH ...  Keep it simple.
-                for i in 0..width {
-                    // println!("Column {i}:");
-                    let mut g = grp.column(i);
-                    group_process(self, g);
-                    // println!("Row {i}:");
-                    g = grp.row(i);
-                    group_process(self, g);
-                    // println!("Cell {i}:");
-                    g = grp.cell(i);
-                    group_process(self, g);
-                }
-
-                if found_something == true {
-                    pass2 = true;
-                    // Ok, pass 2 found something.
-                    found_something = false;
-                    continue;
-                }
-
-                //
-                // - If pass1 set, reset the found_something (because it
-                //   did find something)
-                // - Clear the pass1_again flag, we're done with pass 1.
-                if pass1 {
-                    pass1_again = false;
-                    found_something = true;
-                } else {
-                    // Ok, we didn't find anything.
-                    // Break out of loop, get unstuck.
-                    break;
-                }
-            }
-        }
 
-        // Pass 3:
-        // - Find pairs & remove those numbers from corresponding group.
+                        // println!("values {:?}", values);
 
-        let grp = self.group.clone();
+                        // Now, check for singles.
+                        for v in values.iter() {
+                            // println!("Check Value: {}", v);
 
-        println!("Pass 3:");
-        self.board.display();
-        self.possible.display();
+                            let mut count = 0;
+                            let mut pos = 0;
 
-        assert_eq!(self.board.width, self.possible.width);
+                            for gidx in 0..width {
+                                if this.possible.possible[grp[gidx as usize]].get(v as usize) {
+                                    // if this.possible[grp.0[gidx as usize] as usize].contains(&v) {
+                                    count += 1;
+                                    pos = grp[gidx as usize];
+                                    if count > 1 {
+                                        break;
+                                    } else {
+                                        // print!(" IDX {} POS {} ", gidx, pos);
+                                    }
+                                }
+                            }
+                            if count == 1 {
+                                // don't need this, it was v!
+                                // let value = this.possible[pos as usize].iter().next().cloned().unwrap();
+                                let xy = this.board.xy(pos);
+                                // this.possible.display();
+                                // this.board.display();
+                                this.set(xy.0, xy.1, v + 1);
+                                // println!("SET {} ({},{}) = {}", pos, xy.0 + 1, xy.1 + 1, v+1);
+
+                                found_something = true;
+                            }
+                        }
+                    };
+
+                    // Change to 0..WIDTH ...  Keep it simple.
+                    for i in 0..width {
+                        // println!("Column {i}:");
+                        let mut g = grp.column(i);
+                        group_process(self, g);
+                        // println!("Row {i}:");
+                        g = grp.row(i);
+                        group_process(self, g);
+                        // println!("Cell {i}:");
+                        g = grp.cell(i);
+                        group_process(self, g);
+                    }
 
-        // Pair processing.
-        for i in 0..width {
-            let mut g = grp.cell(i);
-            println!("Cell {}: {:?}", i, g);
+                    if found_something == true {
+                        pass2 = true;
+                        // Ok, pass 2 found something.
+                        found_something = false;
+                        continue;
+                    }
 
-            for gidx in 0..WIDTH - 1 {
-                let gpos = g[gidx as usize];
-                if self.possible.possible[gpos].count_set() == 2 {
-                    // Found a pair
+                    //
+                    // - If pass1 set, reset the found_something (because it
+                    //   did find something)
+                    // - Clear the pass1_again flag, we're done with pass 1.
+                    if pass1 {
+                        pass1_again = false;
+                        found_something = true;
+                    } else {
+                        // Ok, we didn't find anything.
+                        // Break out of loop, get unstuck.
+                        break;
+                    }
+                }
+            }
 
-                    for fidx in gidx + 1..width {
-                        let fpos = g[fidx as usize];
-                        if self.possible.possible[fpos as usize].count_set() == 2 {
-                            // Ok, there's another pair
-                            // if self.possible[gpos as usize].is_subset(&self.possible[fpos as usize])
+            // Pass 3:
+            // - Find pairs & remove those numbers from corresponding group.
 
-                            if self.possible.possible[gpos] == self.possible.possible[fpos] {
-                                // Ok, they have the same values!
-                                // Ok, remove the items in the pair from the cell.
-                                // Don't touch the gpos/fpos records.  Keep those!
+            let grp = self.group.clone();
 
-                                // This looks .. WRONG!  only z+1 when using set(value)!
+            println!("Pass 3:");
+            self.board.display();
+            self.possible.display();
 
-                                let mut values: [u8; 2] = [0, 0];
-                                let mut vpos = 0;
-                                for z in self.possible.possible[gpos].iter() {
-                                    values[vpos] = z;
-                                    vpos += 1;
-                                }
+            assert_eq!(self.board.width, self.possible.width);
 
-                                // Ok, other then being off by 1 (because x,y starts at 0 not 1),
-                                // This is, at least, displaying the information properly.
+            // Pair processing.
+            for i in 0..width {
+                let mut g = grp.cell(i);
+                println!("Cell {}: {:?}", i, g);
 
-                                self.possible.display();
-                                println!(
-                                    "Pairs {gpos}({},{}) and {fpos}({},{}) {:?}",
-                                    self.possible.xy(gpos).0 + 1,
-                                    self.possible.xy(gpos).1 + 1,
-                                    self.possible.xy(fpos).0 + 1,
-                                    self.possible.xy(fpos).1 + 1,
-                                    values
-                                );
+                for gidx in 0..WIDTH - 1 {
+                    let gpos = g[gidx as usize];
+                    if self.possible.possible[gpos].count_set() == 2 {
+                        // Found a pair
 
-                                let mut pair_removed = false;
+                        for fidx in gidx + 1..width {
+                            let fpos = g[fidx as usize];
+                            if self.possible.possible[fpos as usize].count_set() == 2 {
+                                // Ok, there's another pair
+                                // if self.possible[gpos as usize].is_subset(&self.possible[fpos as usize])
 
-                                // Check to see if anything was removed.
+                                if self.possible.possible[gpos] == self.possible.possible[fpos] {
+                                    // Ok, they have the same values!
+                                    // Ok, remove the items in the pair from the cell.
+                                    // Don't touch the gpos/fpos records.  Keep those!
 
-                                for remove in 0..width {
-                                    if (gidx == remove) || (fidx == remove) {
-                                        // Skip the found pair indexes.  Don't remove those!
-                                        continue;
-                                    }
+                                    // This looks .. WRONG!  only z+1 when using set(value)!
 
-                                    // Ok, these aren't the ones to save, so:
-                                    let rpos = g[remove as usize];
-                                    if self.possible.possible[rpos].get(values[0] as usize) {
-                                        self.possible.possible[rpos].set(values[0] as usize, false);
-                                        found_something = true;
-                                        pair_removed = true;
-                                        println!("Removed {} from {}({},{})", values[0], rpos, self.possible.xy(rpos).0, self.possible.xy(rpos).1);
+                                    let mut values: [u8; 2] = [0, 0];
+                                    let mut vpos = 0;
+                                    for z in self.possible.possible[gpos].iter() {
+                                        values[vpos] = z;
+                                        vpos += 1;
                                     }
 
-                                    if self.possible.possible[rpos].get(values[1] as usize) {
-                                        self.possible.possible[rpos].set(values[1] as usize, false);
-                                        found_something = true;
-                                        pair_removed = true;
-                                        println!("Removed {} from {}({},{})", values[1], rpos, self.possible.xy(rpos).0, self.possible.xy(rpos).1);
-                                    }
-                                }
+                                    // Ok, other then being off by 1 (because x,y starts at 0 not 1),
+                                    // This is, at least, displaying the information properly.
 
-                                if pair_removed {
-                                    println!("pair removed...");
+                                    self.possible.display();
                                     println!(
-                                        "--> Pairs {gpos}({},{}) and {fpos}({},{}) {:?}",
+                                        "Pairs {gpos}({},{}) and {fpos}({},{}) {:?}",
                                         self.possible.xy(gpos).0 + 1,
                                         self.possible.xy(gpos).1 + 1,
                                         self.possible.xy(fpos).0 + 1,
                                         self.possible.xy(fpos).1 + 1,
                                         values
                                     );
-                                }
 
-                                // Check the x's and y's to see if we can also process a row/column too.
-                                if self.possible.xy(gpos).0 == self.possible.xy(fpos).0 {
-                                    // Matching X - process column
-                                    let column = xy(gpos).0;
+                                    let mut pair_removed = false;
 
-                                    vpos = 0;
-                                    for z in self.possible.possible[gpos].iter() {
-                                        values[vpos] = z + 1;
-                                        vpos += 1;
-                                    }
-                                    for remove in 0..WIDTH {
-                                        if (remove == xy(gpos).1) || (remove == xy(fpos).1) {
+                                    // Check to see if anything was removed.
+
+                                    for remove in 0..width {
+                                        if (gidx == remove) || (fidx == remove) {
+                                            // Skip the found pair indexes.  Don't remove those!
                                             continue;
                                         }
 
-                                        let pos = self.possible.pos(column, remove);
-
-                                        if self.possible.possible[pos].get(values[0] as usize) {
-                                            self.possible.possible[pos]
-                                                .set(values[0] as usize, false);
+                                        // Ok, these aren't the ones to save, so:
+                                        let rpos = g[remove as usize];
+                                        if self.possible.possible[rpos].get(values[0] as usize) {
+                                            self.possible.possible[rpos].set(values[0] as usize, false);
                                             found_something = true;
                                             pair_removed = true;
+                                            println!("Removed {} from {}({},{})", values[0], rpos, self.possible.xy(rpos).0, self.possible.xy(rpos).1);
                                         }
 
-                                        if self.possible.possible[pos].get(values[1] as usize) {
-                                            self.possible.possible[pos]
-                                                .set(values[1] as usize, false);
+                                        if self.possible.possible[rpos].get(values[1] as usize) {
+                                            self.possible.possible[rpos].set(values[1] as usize, false);
                                             found_something = true;
                                             pair_removed = true;
+                                            println!("Removed {} from {}({},{})", values[1], rpos, self.possible.xy(rpos).0, self.possible.xy(rpos).1);
                                         }
                                     }
-                                }
-
-                                if self.possible.xy(gpos).1 == self.possible.xy(fpos).1 {
-                                    // Matching Y - process row
-                                    let row = self.possible.xy(gpos).1;
 
-                                    vpos = 0;
-                                    for z in self.possible.possible[gpos].iter() {
-                                        values[vpos] = z + 1;
-                                        vpos += 1;
+                                    if pair_removed {
+                                        println!("pair removed...");
+                                        println!(
+                                            "--> Pairs {gpos}({},{}) and {fpos}({},{}) {:?}",
+                                            self.possible.xy(gpos).0 + 1,
+                                            self.possible.xy(gpos).1 + 1,
+                                            self.possible.xy(fpos).0 + 1,
+                                            self.possible.xy(fpos).1 + 1,
+                                            values
+                                        );
                                     }
-                                    for remove in 0..width {
-                                        if (remove == self.possible.xy(gpos).0)
-                                            || (remove == self.possible.xy(fpos).0)
-                                        {
-                                            continue;
-                                        }
-                                        let pos = self.possible.pos(remove, row);
 
-                                        if self.possible.possible[pos].get(values[0] as usize) {
-                                            self.possible.possible[pos]
-                                                .set(values[0] as usize, false);
-                                            found_something = true;
-                                            pair_removed = true;
+                                    // Check the x's and y's to see if we can also process a row/column too.
+                                    if self.possible.xy(gpos).0 == self.possible.xy(fpos).0 {
+                                        // Matching X - process column
+                                        let column = xy(gpos).0;
+
+                                        vpos = 0;
+                                        for z in self.possible.possible[gpos].iter() {
+                                            values[vpos] = z + 1;
+                                            vpos += 1;
                                         }
+                                        for remove in 0..WIDTH {
+                                            if (remove == xy(gpos).1) || (remove == xy(fpos).1) {
+                                                continue;
+                                            }
+
+                                            let pos = self.possible.pos(column, remove);
+
+                                            if self.possible.possible[pos].get(values[0] as usize) {
+                                                self.possible.possible[pos]
+                                                    .set(values[0] as usize, false);
+                                                found_something = true;
+                                                pair_removed = true;
+                                            }
+
+                                            if self.possible.possible[pos].get(values[1] as usize) {
+                                                self.possible.possible[pos]
+                                                    .set(values[1] as usize, false);
+                                                found_something = true;
+                                                pair_removed = true;
+                                            }
+                                        }
+                                    }
 
-                                        if self.possible.possible[pos].get(values[1] as usize) {
-                                            self.possible.possible[pos]
-                                                .set(values[1] as usize, false);
-                                            found_something = true;
-                                            pair_removed = true;
+                                    if self.possible.xy(gpos).1 == self.possible.xy(fpos).1 {
+                                        // Matching Y - process row
+                                        let row = self.possible.xy(gpos).1;
+
+                                        vpos = 0;
+                                        for z in self.possible.possible[gpos].iter() {
+                                            values[vpos] = z + 1;
+                                            vpos += 1;
+                                        }
+                                        for remove in 0..width {
+                                            if (remove == self.possible.xy(gpos).0)
+                                                || (remove == self.possible.xy(fpos).0)
+                                            {
+                                                continue;
+                                            }
+                                            let pos = self.possible.pos(remove, row);
+
+                                            if self.possible.possible[pos].get(values[0] as usize) {
+                                                self.possible.possible[pos]
+                                                    .set(values[0] as usize, false);
+                                                found_something = true;
+                                                pair_removed = true;
+                                            }
+
+                                            if self.possible.possible[pos].get(values[1] as usize) {
+                                                self.possible.possible[pos]
+                                                    .set(values[1] as usize, false);
+                                                found_something = true;
+                                                pair_removed = true;
+                                            }
                                         }
                                     }
-                                }
 
-                                if pair_removed {
-                                    if true {
-                                        println!(
-                                            "Pair found! {} {}: {} {:?} and {} {:?} !",
-                                            gidx,
-                                            fidx,
-                                            gpos,
-                                            self.board.xy(gpos),
-                                            fpos,
-                                            self.board.xy(fpos)
-                                        );
-                                        self.possible.display();
-                                        // panic!("... We're lost ...");
+                                    if pair_removed {
+                                        if true {
+                                            println!(
+                                                "Pair found! {} {}: {} {:?} and {} {:?} !",
+                                                gidx,
+                                                fidx,
+                                                gpos,
+                                                self.board.xy(gpos),
+                                                fpos,
+                                                self.board.xy(fpos)
+                                            );
+                                            self.possible.display();
+                                            // panic!("... We're lost ...");
+                                        }
                                     }
                                 }
                             }
@@ -1354,10 +1282,12 @@ impl AnySolver {
                     }
                 }
             }
+            println!("Pass 3 - Ending...");
+            found_something
+            */
         }
-        println!("Pass 3 - Ending...");
-        found_something
-        */
+        self.board.complete()
+
     }
 }
 
@@ -1396,9 +1326,8 @@ mod tests {
         assert!(solver.validate_board());
 
         solver.reset_possible();
-        // solver.solve_logic();
 
-        while (solver.solve_logic()) {
+        if solver.solve_logic() {
             solver.board.display();
         }
 
@@ -1436,7 +1365,7 @@ mod tests {
         assert!(solver.validate_board());
         solver.board.display();
 
-        while (solver.solve_logic()) {
+        if solver.solve_logic() {
             solver.board.display();
         }
 
@@ -1546,17 +1475,6 @@ mod tests {
             let solutions = solver.board.brute_force_solver(2);
             assert!(solutions.0 == 1);
         }
-
-        /*
-        let mut board: AnyBoard = AnyBoard::new(5);
-        let result = board.load_from_tld('b', '_', "_m_kzg____h_s_n____ftd_u_u_dh_____f_b_t_w_____yg_c_rl_o_tdhy__m__uvig_w_sk_eg___p_q_jikouys_r_d___mlq_t_sb_emcwg_dlzyo_kp_i_ng__ir_b_fp_vhz_ce_y_jm__w__m__o_k_xul_qbt_d_s__e____otv_dhegn___mfkpz_blr____s_dv_n_mjx_ckg_w_bo_p___kqyelwjcz_____nxumoisdh_z__fp_vbi_______dkx_eg__r_y_mlwf_u__q_i__o_chdv_j_i_he_r_____________p_zl_k_d_vbjh_y__e_p__s_tguc_q_s__qj_kpn_______ufw_hx__i_hvntirfxw_____lbckympjg___u_kz_m_bfn_yvx_h_ir_o____rgm_otlnx___ipfes_kwc____p__c_v_ugh_krj_m_w__x__x__ci_j_qk_mpo_dr_u_zb__ht_i_qe_wjvcy_bhkzx_ng_u_syv___u_c_hsfrlqo_t_e___pj_cn_h_slzr__j__mqgp_y_vd_m_bs_____t_o_n_h_____ez_f_e_ufd____p_g_z____cqr_x_");
-        assert!(result.is_ok());
-        board.display();
-
-        let mut solver = AnySolver::new(&board);
-        assert!(solver.validate_board());
-        assert!(solver.brute_force_solver() == 1);
-        */
     }
 
     #[test]
@@ -1632,861 +1550,50 @@ mod tests {
     }
 }
 
-/*
-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.
-
-Right now, I have &mut of board, it might be better to just copy it.
-Then, I could derive Clone and Copy again for BoardPossible...
-
-(And simplify things immensely, getting rid of lifetimes...)
-
-Still thinking of having Possible as a structure, so I could implement
-funcs on just that, rather then having them in BoardPossible (wrong
-place for Possible's implementation).
- */
-
-/*
-#[derive(Debug, Clone, Copy)]
-pub struct SudokuPossible {
-    pub possible: [Possible; MAX_SIZE as usize];
-}
-
-        // 10 = WIDTH + 1
-        // This would need to be changed in order to handle 4x4 or 5x5.
-        // NOTE: We ignore bit 0, we use bits 1-9 (for 3x3).
-        let mut initial: Bits = Bits(set_bits(10));
-        initial.set(0, false);
-
-        let s = Sudoku {
-            board: [0; MAX_SIZE as usize],
-            possible: [initial; MAX_SIZE as usize],
-
-*/
+/* 
+    /// Puzzle generation
+    /// - Removes a number, tests to see if the puzzle can still be solved by logic.
+    /// - Returns true when still a valid, solvable puzzle.
+    /// - Otherwise, restores number and returns false.
+    pub fn remove(&mut self) -> bool {
+        // Find a number, remove it. Save position.
+        let mut rng = ChaCha20Rng::from_entropy();
+        let puzrange = Uniform::new(0, WIDTH);
+        let mut x = 0;
+        let mut y = 0;
+        let mut value: u8 = 0;
 
-/*
-#[derive(Debug)]
-pub struct BoardPossible<'a> {
-    board: &'a mut Board,
-    possible: [Bits; MAX_SIZE as usize],
-}
+        while value == 0 {
+            x = puzrange.sample(&mut rng);
+            y = puzrange.sample(&mut rng);
+            value = self.get(x, y);
+        }
 
-impl<'a> BoardPossible<'a> {
-    pub fn new(board: &'a mut Board) -> Self {
-        // 10 = WIDTH + 1
-        // This would need to be changed in order to handle 4x4 or 5x5.
-        // NOTE: We ignore bit 0, we use bits 1-9 (for 3x3).
-        let mut initial: Bits = Bits(set_bits(10));
-        initial.set(0, false);
+        self.set(x, y, 0);
 
-        let mut s = Self {
-            board: board,
-            possible: [initial; MAX_SIZE as usize],
-        };
-        s.reset_possible();
-        s
-    }
+        // Clone, and solve by logic.
+        let mut puzcopy = self.clone();
 
-    pub fn clear_possible(&mut self) {
-        let mut initial: Bits = Bits(set_bits(10));
-        initial.set(0, false);
-        self.possible = [initial; MAX_SIZE as usize];
-    }
+        puzcopy.reset_possible();
+        /*
+        puzcopy.display();
+        puzcopy.display_possible();
+         */
+        // If solvable, return true.
+        while puzcopy.solve(false) {}
 
-    /// set (x,y) with value.
-    /// - This updates the board.
-    /// - this updates all the possible (row,column,cell).
-    /// - Clears the possible for the (x,y).
-    pub fn set(&mut self, x: u8, y: u8, value: u8) {
-        self.board.0[pos(x, y)] = value;
+        /*
+        puzcopy.display();
+        puzcopy.display_possible();
+        */
 
-        // update the possible
-        let mut g: &Group = for_row(y);
-        for g in g.0 {
-            self.possible[g].set(value, false);
-        }
-        g = for_column(x);
-        for g in g.0 {
-            self.possible[g].set(value, false);
-        }
-        g = for_cell(which_cell(x, y));
-        for g in g.0 {
-            self.possible[g].set(value, false);
+        if puzcopy.puzzle_complete() {
+            return true;
         }
-        self.possible[pos(x, y)].clear();
-    }
-
-    pub fn reset_possible(&mut self) {}
-
-    /// 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.possible[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!("");
-        }
+        // If not solvable, restore number, return false.
+        self.set(x, y, value);
+        return false;
     }
-}
 */
-
-/*
-  ___  _     _    ____          _
- / _ \| | __| |  / ___|___   __| | ___
-| | | | |/ _` | | |   / _ \ / _` |/ _ \
-| |_| | | (_| | | |__| (_) | (_| |  __/
- \___/|_|\__,_|  \____\___/ \__,_|\___|
-
- */
-
-#[derive(Debug, Clone, Copy)]
-pub struct Sudoku {
-    pub board: [u8; MAX_SIZE as usize],      // Board
-    pub possible: [Bits; MAX_SIZE as usize], // BoardPossible
-}
-
-/// Translate x,y to position in board.
-/// This is used as usize, so return that instead of u8.
-pub const fn pos(x: u8, y: u8) -> usize {
-    x as usize + (y as usize * WIDTH as usize)
-}
-
-/// Translate x,y (with starting index of 1) to position in board.
-pub const fn pos1(x: u8, y: u8) -> usize {
-    (x as usize - 1) + ((y as usize - 1) * WIDTH as usize)
-}
-
-/// Translate post to x,y in board.
-pub const fn xy(pos: usize) -> (u8, u8) {
-    ((pos % WIDTH as usize) as u8, (pos / WIDTH as usize) as u8)
-}
-
-const DEBUG_OUTPUT: bool = false;
-
-/*
-(0 .. 10)
-                        .map(|_| HashSet::<usize>::new())
-                        .collect();
-
-let arr: [Vec<u32>; 10] = [(); 10].map(|_| Vec::with_capacity(100));
-
-*/
-
-impl Sudoku {
-    pub fn new() -> Self {
-        // 10 = WIDTH + 1
-        // This would need to be changed in order to handle 4x4 or 5x5.
-        // NOTE: We ignore bit 0, we use bits 1-9 (for 3x3).
-        let mut initial: Bits = Bits(set_bits(10));
-        initial.set(0, false);
-
-        let s = Sudoku {
-            board: [0; MAX_SIZE as usize],
-            possible: [initial; MAX_SIZE as usize],
-        };
-        s
-    }
-
-    pub fn clear_possible(&mut self) {
-        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 = Bits(set_bits(10));
-        initial.set(0, false);
-
-        self.board = [0; MAX_SIZE as usize];
-        self.possible = [initial; MAX_SIZE as usize];
-    }
-
-    /// Load puzzle from a string.
-    /// Note, we load from (top,left) going down, to (bottom,left) by columns.
-    pub fn load_from_tld(&mut self, start_ch: char, blank: char, s: &str) {
-        self.clear();
-        let mut x: u8 = 0;
-        let mut y: u8 = 0;
-
-        for ch in s.chars() {
-            if ch != blank {
-                self.set(x, y, (ch as u8 - start_ch as u8) + 1);
-            }
-            y += 1;
-            if y >= WIDTH {
-                y = 0;
-                x += 1;
-            }
-        }
-    }
-
-    /// Load puzzle from a string.
-    /// This loads from (top,left) going right, to (top,right), by rows.
-    pub fn load_from_tlr(&mut self, start_ch: char, blank: char, s: &str) {
-        self.clear();
-        let mut i: usize = 0;
-
-        for ch in s.chars() {
-            if ch != blank {
-                self.set(xy(i).0, xy(i).1, (ch as u8 - start_ch as u8) + 1);
-            }
-            i += 1;
-        }
-    }
-
-    pub fn save_to_tld(&self, mut start_ch: char, blank: char) -> String {
-        let mut result = String::new();
-        result.reserve(MAX_SIZE as usize);
-        start_ch = (start_ch as u8 - 1) as char;
-        let mut x: u8 = 0;
-        let mut y: u8 = 0;
-
-        for _i in 0..MAX_SIZE {
-            if self.board[pos(x, y) as usize] == 0 {
-                result.push(blank);
-            } else {
-                result.push((start_ch as u8 + self.board[pos(x, y) as usize]) as char);
-            }
-            y += 1;
-            if y >= WIDTH {
-                y = 0;
-                x += 1;
-            }
-        }
-        result
-    }
-
-    pub fn save_to_tlr(&self, mut start_ch: char, blank: char) -> String {
-        let mut result = String::new();
-        result.reserve(MAX_SIZE as usize);
-        start_ch = (start_ch as u8 - 1) as char;
-        for i in 0..MAX_SIZE {
-            if self.board[i as usize] == 0 {
-                result.push(blank);
-            } else {
-                result.push((start_ch as u8 + self.board[i as usize]) as char);
-            }
-        }
-        result
-    }
-
-    pub fn get(&self, x: u8, y: u8) -> u8 {
-        self.board[pos(x, y) as usize]
-    }
-
-    /*
-    This set does more then it needs to.
-    When setting a location, it also updates the possible.
-    This needs to be moved into something else.  Putting it into Possible?
-     */
-
-    pub fn set(&mut self, x: u8, y: u8, value: u8) {
-        self.board[pos(x, y) as usize] = value;
-        // Ok, update the possible
-        let mut g = for_row(y);
-        // g.for_row(x, y);
-        for g in g.0 {
-            // remove value from these sets.
-            self.possible[g as usize].set(value, false);
-            // self.possible[g as usize].take(&value);
-        }
-        g = for_column(x);
-        // g.for_column(x, y);
-        for g in g.0 {
-            // remove value from these sets.
-            self.possible[g as usize].set(value, false);
-            // self.possible[g as usize].take(&value);
-        }
-        g = for_cell(which_cell(x, y));
-        // g.for_block(x, y);
-        for g in g.0 {
-            // remove value from these sets.
-            self.possible[g as usize].set(value, false);
-            // self.possible[g as usize].take(&value);
-        }
-        self.possible[pos(x, y) as usize].clear();
-    }
-
-    /// Reset the Possible
-    /// - For when a new puzzle has been loaded.
-    /// - When something has changed, and the possibles are out of sync.
-    pub fn reset_possible(&mut self) {
-        // Reset the possible.
-        self.clear_possible();
-        for y in 0..WIDTH {
-            for x in 0..WIDTH {
-                let item: u8 = self.board[pos(x as u8, y as u8) as usize];
-                if item != 0 {
-                    let mut g: &Group = for_row(y);
-                    for g in g.0 {
-                        self.possible[g as usize].set(item, false);
-                    }
-                    g = for_column(x);
-                    for g in g.0 {
-                        self.possible[g as usize].set(item, false);
-                    }
-                    g = for_cell(which_cell(x, y));
-                    for g in g.0 {
-                        self.possible[g as usize].set(item, false);
-                    }
-                    self.possible[pos(x, y) as usize].clear();
-                }
-            }
-        }
-    }
-
-    /// Display the sudoku puzzle.
-    pub fn display(&self) {
-        println!("╔═══╦═══╦═══╗");
-        for y in 0..WIDTH {
-            print!("║");
-            for x in 0..WIDTH {
-                let item = self.board[pos(x as u8, y as u8) as usize];
-                if item == 0 {
-                    print!(" ");
-                } else if (item >= 1) && (item <= 9) {
-                    print!("{}", item);
-                }
-                if x % 3 == 2 {
-                    print!("║");
-                }
-            }
-            println!("");
-            if y % 3 == 2 {
-                if y + 1 == WIDTH {
-                    println!("╚═══╩═══╩═══╝");
-                } else {
-                    println!("╠═══╬═══╬═══╣");
-                }
-            }
-        }
-    }
-
-    /// Display the possibles.
-    /// This should be in the Possible struct, not here.
-    pub fn display_possible(&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.possible[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!("");
-        }
-    }
-
-    /// Is the puzzle complete?
-    /// Have all of the locations been filled with a value?
-    /// - This does not validate that it is a correct puzzle,
-    ///   - It doesn't check for duplicate digits (for example).
-    pub fn puzzle_complete(&self) -> bool {
-        for i in 0..MAX_SIZE {
-            if self.board[i as usize] == 0 {
-                return false;
-            }
-        }
-        true
-    }
-
-    /// Recursive brute-force solver
-    /// - As possibilities are tried, it recursively calls itself to see
-    ///   if there are any solutions with the given possibility.
-    fn calculate_possible(
-        &mut self,
-        total_solutions: &mut u16,
-        solutions: &mut Vec<SudokuBoard>,
-    ) -> bool {
-        for idx in 0..MAX_SIZE as usize {
-            if self.board[idx as usize] == 0 {
-                // Ok, there's a blank here
-
-                let (x, y) = xy(idx);
-                if DEBUG_OUTPUT {
-                    println!("idx={} ({},{})", idx, x, y);
-                    self.display();
-                }
-
-                'outer: for possible in 1..=9 {
-                    let mut g = for_row(y);
-                    for p in g.0 {
-                        if self.board[p as usize] == possible {
-                            continue 'outer;
-                        }
-                    }
-                    g = for_column(x);
-                    for p in g.0 {
-                        if self.board[p as usize] == possible {
-                            continue 'outer;
-                        }
-                    }
-                    // check cell
-                    let cell = which_cell(x, y);
-                    g = for_cell(cell);
-                    for p in g.0 {
-                        if self.board[p as usize] == possible {
-                            continue 'outer;
-                        }
-                    }
-
-                    // Ok, it could go here!
-                    if DEBUG_OUTPUT {
-                        println!("({},{})={}", x, y, possible);
-                    }
-
-                    self.board[idx as usize] = possible;
-                    if self.puzzle_complete() {
-                        if *total_solutions < solutions.capacity() as u16 {
-                            solutions.push(self.board);
-                        }
-                        *total_solutions += 1;
-                        /*
-                        println!("**SOLUTION**");
-                        self.display();
-                        println!("***");
-                         */
-                        break;
-                    } else {
-                        if self.calculate_possible(total_solutions, solutions) {
-                            return true;
-                        }
-                    }
-                }
-                self.board[idx as usize] = 0;
-                return false;
-            }
-        }
-
-        false
-    }
-
-    /// Brute-force solver
-    /// - Prints out a (one) solution.
-    /// - Returns the number of solutions found.
-    pub fn bruteforce_solver(&self) -> u16 {
-        let mut workset = Sudoku {
-            board: self.board,
-            possible: [Bits(0); MAX_SIZE as usize],
-        };
-
-        let mut total_solutions: u16 = 0;
-        let mut solutions = Vec::new();
-        solutions.reserve(1);
-        workset.calculate_possible(&mut total_solutions, &mut solutions);
-
-        // return number of solutions.
-        if solutions.len() > 0 {
-            println!("*** A solution:");
-            workset.board = solutions[0];
-            workset.display();
-            println!("***");
-        }
-        total_solutions
-    }
-
-    /// Make a sudoku puzzle.
-    /// This gives us a fully solved puzzle.
-    pub fn make(&mut self) {
-        let mut rng = ChaCha20Rng::from_entropy();
-
-        self.fill_board(&mut rng);
-        // Ok, this gives us a random (but fully solved) puzzle.
-    }
-
-    /// Fill puzzle with random
-    /// - This is like the brute-force solver, it calls itself recursively
-    ///   and backtraces if a solution can't be found.
-    fn fill_board(&mut self, rng: &mut ChaCha20Rng) -> bool {
-        let backup = Sudoku {
-            board: self.board,
-            possible: self.possible,
-        };
-
-        for idx in 0..MAX_SIZE as usize {
-            if self.board[idx as usize] == 0 {
-                let (x, y) = xy(idx);
-                let mut available: [u8; WIDTH as usize] = [0; WIDTH as usize];
-                let mut total_available: u8 = 0;
-
-                for t in self.possible[idx as usize].iter() {
-                    available[total_available as usize] = t;
-                    total_available += 1;
-                }
-
-                if total_available == 0 {
-                    // No possible moves remain.
-                    /*
-                    self.board = backup.board;
-                    self.possible = backup.possible;
-                     */
-                    return false;
-                }
-
-                // Randomize the possible items.
-                available[0..total_available as usize].shuffle(rng);
-                for v_idx in 0..total_available {
-                    let value = available[v_idx as usize];
-                    self.set(x, y, value);
-                    if self.fill_board(rng) {
-                        return true;
-                    }
-                    // failure
-                    self.board = backup.board;
-                    self.possible = backup.possible;
-                }
-
-                // We've run out of possible.
-                return false;
-            }
-        }
-
-        // We've visited everything, and it isn't 0.
-        return true;
-    }
-
-    /// Puzzle generation
-    /// - Removes a number, tests to see if the puzzle can still be solved by logic.
-    /// - Returns true when still a valid, solvable puzzle.
-    /// - Otherwise, restores number and returns false.
-    pub fn remove(&mut self) -> bool {
-        // Find a number, remove it. Save position.
-        let mut rng = ChaCha20Rng::from_entropy();
-        let puzrange = Uniform::new(0, WIDTH);
-        let mut x = 0;
-        let mut y = 0;
-        let mut value: u8 = 0;
-
-        while value == 0 {
-            x = puzrange.sample(&mut rng);
-            y = puzrange.sample(&mut rng);
-            value = self.get(x, y);
-        }
-
-        self.set(x, y, 0);
-
-        // Clone, and solve by logic.
-        let mut puzcopy = self.clone();
-
-        puzcopy.reset_possible();
-        /*
-        puzcopy.display();
-        puzcopy.display_possible();
-         */
-        // If solvable, return true.
-        while puzcopy.solve(false) {}
-
-        /*
-        puzcopy.display();
-        puzcopy.display_possible();
-        */
-
-        if puzcopy.puzzle_complete() {
-            return true;
-        }
-
-        // If not solvable, restore number, return false.
-        self.set(x, y, value);
-        return false;
-    }
-
-    /*
-    fn make_(&mut self) {
-        self.clear();
-
-        let mut rng = ChaCha20Rng::from_entropy();
-
-        let pick_one = |this: &Self, rng: &mut ChaCha20Rng, idx: u8| -> Option<u8> {
-            let mut available: [u8; WIDTH as usize] = [0; WIDTH as usize];
-            let mut total_available: u8 = 0;
-
-            for t in this.possible[idx as usize].iter() {
-                available[total_available as usize] = t;
-                total_available += 1;
-            }
-            if total_available == 1 {
-                return Some(available[0]);
-            }
-            if total_available == 0 {
-                return None;
-            }
-            Some(available[rng.gen_range(0..total_available as usize)])
-        };
-
-        for i in 0..MAX_SIZE {
-            let (x, y) = xy(i);
-            if self.board[i as usize] == 0 {
-                // Ok, we found a blank space.
-                let value = pick_one(self, &mut rng, i);
-                if value.is_some() {
-                    let value = value.unwrap();
-                    if DEBUG_OUTPUT {
-                        println!("Set({},{})={}", x, y, value);
-                    }
-                    self.set(x, y, value);
-                }
-            }
-        }
-    }
-    */
-
-    /// Solve, using logic alone
-    /// - Returns true when something was added to the board.
-    /// - Call solve until it returns false.
-    pub fn solve(&mut self, debug: bool) -> bool {
-        // Pass 1: Look for singles in the possible sets.
-        let mut found_something = false;
-
-        for i in 0..MAX_SIZE as usize {
-            if self.possible[i as usize].count_set() == 1 {
-                // Get the value
-                let value = self.possible[i as usize].iter().next().unwrap();
-                // Found one!
-                if debug {
-                    println!("Set1 {:?} to {}", xy(i), value);
-                }
-                self.set(xy(i).0, xy(i).1, value);
-                found_something = true;
-            }
-        }
-
-        let mut g = Group::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.
-            values.clear();
-            for gidx in 0..WIDTH {
-                // println!("possible: {:?}", this.possible[grp.items[gidx as usize] as usize]);
-                for v in this.possible[grp.0[gidx as usize] as usize].iter() {
-                    values.set(v, true);
-                }
-                // values.extend(this.possible[grp.0[gidx as usize] as usize]);
-                // println!("now     : {:?}", this.possible[grp.items[gidx as usize] as usize]);
-            }
-
-            // println!("values {:?}", values);
-
-            // Now, check for singles.
-            for v in values.iter() {
-                let mut count = 0;
-                let mut pos = 0;
-                for gidx in 0..WIDTH {
-                    if this.possible[grp.0[gidx as usize] as usize].get(v) {
-                        // if this.possible[grp.0[gidx as usize] as usize].contains(&v) {
-                        count += 1;
-                        pos = grp.0[gidx as usize];
-                        if count > 1 {
-                            break;
-                        }
-                    }
-                }
-                if count == 1 {
-                    // don't need this, it was v!
-                    // let value = this.possible[pos as usize].iter().next().cloned().unwrap();
-                    if debug {
-                        println!("Set2 {:?} to {}", xy(pos), v);
-                    }
-                    this.set(xy(pos).0, xy(pos).1, v);
-                    found_something = true;
-                }
-            }
-        };
-
-        // Change to 0..WIDTH ...  Keep it simple.
-        for i in 0..WIDTH {
-            let mut g = for_column(i);
-            // g.for_column(i, 1);
-            group_process(self, &g);
-            g = for_row(i);
-            // g.for_row(1, i);
-            group_process(self, &g);
-            g = for_cell(i);
-            // g.for_iter(i);
-            group_process(self, &g);
-        }
-
-        if found_something {
-            return found_something;
-        }
-
-        if debug {
-            println!("Looking for pairs...");
-        }
-        // PAIR processing.
-        for i in 0..WIDTH {
-            g.for_iter(i);
-
-            for gidx in 0..WIDTH - 1 {
-                let gpos = g.0[gidx as usize];
-                if self.possible[gpos as usize].count_set() == 2 {
-                    // Found a pair
-                    for fidx in gidx + 1..WIDTH {
-                        let fpos = g.0[fidx as usize];
-                        if self.possible[fpos as usize].count_set() == 2 {
-                            // Ok, there's another pair
-                            // if self.possible[gpos as usize].is_subset(&self.possible[fpos as usize])
-                            if self.possible[gpos as usize] == self.possible[fpos as usize] {
-                                // Ok, they have the same values!
-                                // Ok, remove the items in the pair from the cell.
-                                // Don't touch the gpos/fpos records.  Keep those!
-                                let mut values: [u8; 2] = [0, 0];
-                                let mut vpos = 0;
-                                for z in self.possible[gpos as usize].iter() {
-                                    values[vpos] = z;
-                                    vpos += 1;
-                                }
-
-                                let mut pair_removed = false;
-
-                                // Check to see if anything was removed.
-
-                                for remove in 0..WIDTH {
-                                    if (gidx == remove) || (fidx == remove) {
-                                        continue;
-                                    }
-                                    // Ok, these aren't the ones to save, so:
-                                    let rpos = g.0[remove as usize];
-                                    if self.possible[rpos as usize].get(values[0]) {
-                                        self.possible[rpos as usize].set(values[0], false);
-                                        found_something = true;
-                                        pair_removed = true;
-                                    }
-
-                                    if self.possible[rpos as usize].get(values[1]) {
-                                        self.possible[rpos as usize].set(values[1], false);
-                                        found_something = true;
-                                        pair_removed = true;
-                                    }
-                                }
-
-                                // Check the x's and y's to see if we can also process a row/column too.
-                                if xy(gpos).0 == xy(fpos).0 {
-                                    // Matching X - process column
-                                    let column = xy(gpos).0;
-
-                                    vpos = 0;
-                                    for z in self.possible[gpos as usize].iter() {
-                                        values[vpos] = z;
-                                        vpos += 1;
-                                    }
-                                    for remove in 0..WIDTH {
-                                        if (remove == xy(gpos).1) || (remove == xy(fpos).1) {
-                                            continue;
-                                        }
-
-                                        if self.possible[pos(column, remove) as usize]
-                                            .get(values[0])
-                                        {
-                                            self.possible[pos(column, remove) as usize]
-                                                .set(values[0], false);
-                                            found_something = true;
-                                            pair_removed = true;
-                                        }
-
-                                        if self.possible[pos(column, remove) as usize]
-                                            .get(values[1])
-                                        {
-                                            self.possible[pos(column, remove) as usize]
-                                                .set(values[1], false);
-                                            found_something = true;
-                                            pair_removed = true;
-                                        }
-                                    }
-                                }
-
-                                if xy(gpos).1 == xy(fpos).1 {
-                                    // Matching Y - process row
-                                    let row = xy(gpos).1;
-
-                                    vpos = 0;
-                                    for z in self.possible[gpos as usize].iter() {
-                                        values[vpos] = z;
-                                        vpos += 1;
-                                    }
-                                    for remove in 0..WIDTH {
-                                        if (remove == xy(gpos).0) || (remove == xy(fpos).0) {
-                                            continue;
-                                        }
-                                        if self.possible[pos(remove, row) as usize].get(values[0]) {
-                                            self.possible[pos(remove, row) as usize]
-                                                .set(values[0], false);
-                                            found_something = true;
-                                            pair_removed = true;
-                                        }
-
-                                        if self.possible[pos(remove, row) as usize].get(values[1]) {
-                                            self.possible[pos(remove, row) as usize]
-                                                .set(values[1], false);
-                                            found_something = true;
-                                            pair_removed = true;
-                                        }
-                                    }
-                                }
-
-                                if pair_removed {
-                                    if debug {
-                                        println!(
-                                            "Pair found! {} {}: {} {:?} and {} {:?} !",
-                                            gidx,
-                                            fidx,
-                                            gpos,
-                                            xy(gpos),
-                                            fpos,
-                                            xy(fpos)
-                                        );
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        found_something
-    }
-}
+