|  | @@ -553,6 +553,102 @@ impl AnyPossible {
 | 
	
		
			
				|  |  |          (pos, max)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    pub fn find_pairs(&mut self, cellgroup: &[usize]) -> (Vec<(Vec<u8>, Vec<u8>)>, bool) {
 | 
	
		
			
				|  |  | +        // result[value] = indexes where it is located?
 | 
	
		
			
				|  |  | +        // 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 cellgroup = self.group.group(Groups::Cell, cell_index);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for value in 0..self.width {
 | 
	
		
			
				|  |  | +            for pos in 0..self.width {
 | 
	
		
			
				|  |  | +                let cellindex = cellgroup[pos as usize];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if self.get(cellindex, value as usize + 1)
 | 
	
		
			
				|  |  | +                // .get(self.possible.pos(x, y), value as usize + 1)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    // println!("Found {} ({},{}) = {}", cell_index, x, y, value);
 | 
	
		
			
				|  |  | +                    result[value as usize].set(pos as usize, true);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Step 2: pair them up, and if complete, fixup possible (if needed).
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let zero_bits = GenBits::<u32>(0);
 | 
	
		
			
				|  |  | +        let width = self.width;
 | 
	
		
			
				|  |  | +        let mut possibles_updated: bool = false;
 | 
	
		
			
				|  |  | +        let mut pairs: Vec<(Vec<u8>, Vec<u8>)> = vec![];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        'outer: for idx in 0..width - 1 {
 | 
	
		
			
				|  |  | +            // pos_found contains the positions.
 | 
	
		
			
				|  |  | +            let pos_found = result[idx as usize];
 | 
	
		
			
				|  |  | +            if pos_found == zero_bits {
 | 
	
		
			
				|  |  | +                continue;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if idx > 0 {
 | 
	
		
			
				|  |  | +                // Check previous for matches - already checked...
 | 
	
		
			
				|  |  | +                for check in 0..idx {
 | 
	
		
			
				|  |  | +                    if pos_found == result[check as usize] {
 | 
	
		
			
				|  |  | +                        continue 'outer;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            let count = pos_found.count_set();
 | 
	
		
			
				|  |  | +            if count == 1 {
 | 
	
		
			
				|  |  | +                // Single possible item here ... skip this for now.
 | 
	
		
			
				|  |  | +                continue;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            let mut matches = 1;
 | 
	
		
			
				|  |  | +            // Pos contains the numbers in the cell.
 | 
	
		
			
				|  |  | +            let mut pos = Vec::<u8>::new();
 | 
	
		
			
				|  |  | +            pos.push(idx);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            for look in idx + 1..width {
 | 
	
		
			
				|  |  | +                if result[look as usize] == pos_found {
 | 
	
		
			
				|  |  | +                    matches += 1;
 | 
	
		
			
				|  |  | +                    pos.push(look);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if matches == count {
 | 
	
		
			
				|  |  | +                // Ok! We found a pair (or triple, or quad, or ...)
 | 
	
		
			
				|  |  | +                // Build new possible
 | 
	
		
			
				|  |  | +                let mut new_possible = zero_bits;
 | 
	
		
			
				|  |  | +                for p in &pos {
 | 
	
		
			
				|  |  | +                    new_possible.set(*p as usize, true);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                let mut index_pos: Vec<u8> = Vec::<u8>::new();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                for p in pos_found.iter() {
 | 
	
		
			
				|  |  | +                    index_pos.push(p);
 | 
	
		
			
				|  |  | +                    if self.possible[cellgroup[p as usize]] != new_possible {
 | 
	
		
			
				|  |  | +                        // println!("Update pos {} with {:?}", p, new_possible);
 | 
	
		
			
				|  |  | +                        /* 
 | 
	
		
			
				|  |  | +                        println!(
 | 
	
		
			
				|  |  | +                            "Index is {} => {:?}",
 | 
	
		
			
				|  |  | +                            cellgroup[p as usize],
 | 
	
		
			
				|  |  | +                            self.group.xy(cellgroup[p as usize])
 | 
	
		
			
				|  |  | +                        );
 | 
	
		
			
				|  |  | +                        */
 | 
	
		
			
				|  |  | +                        possibles_updated = true;
 | 
	
		
			
				|  |  | +                        self.possible[cellgroup[p as usize]] = new_possible;
 | 
	
		
			
				|  |  | +                        // println!("Updated!");
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                pairs.push((index_pos, pos));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        (pairs, possibles_updated)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /// Display Possible
 | 
	
		
			
				|  |  |      /// - Collect all of the possibles, with max length.
 | 
	
		
			
				|  |  |      /// - Display formatted (using max length).
 | 
	
	
		
			
				|  | @@ -717,112 +813,8 @@ impl AnySolver {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // OR, just check row and columns?
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /// find_pairs:  Finds the pairs (and triples, and quads, and ...)
 | 
	
		
			
				|  |  | -    /// Must be a vector, because size is self.board.width (dynamic)
 | 
	
		
			
				|  |  | -    /// Returns vector[values 0..width], of positions values are seen.
 | 
	
		
			
				|  |  | -    /// [0] = "1" = vec![list of positions containing a possible 1]
 | 
	
		
			
				|  |  | -    pub fn find_pairs(&mut self, cell_index: u8) -> Vec<GenBits<u32>> {
 | 
	
		
			
				|  |  | -        // result[value] = indexes where it is located?
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        let initial = GenBits::<u32>(0);
 | 
	
		
			
				|  |  | -        let mut result: Vec<GenBits<u32>> = vec![initial; self.board.width as usize];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // Find starting row and column for given cell.
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        // let (col, row) = self.group.cell_start(cell_index);
 | 
	
		
			
				|  |  | -        // let size = self.board.size;
 | 
	
		
			
				|  |  | -        /* 
 | 
	
		
			
				|  |  | -        let size = self.board.size;
 | 
	
		
			
				|  |  | -        let col = (cell_index % size) * size;
 | 
	
		
			
				|  |  | -        let row = (cell_index / size) * size;
 | 
	
		
			
				|  |  | -        */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // println!("Cell {} Starts at {},{}", cell_index, col, row);
 | 
	
		
			
				|  |  | -        let cellgroup = self.group.group(Groups::Cell, cell_index);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        for value in 0..self.board.width {
 | 
	
		
			
				|  |  | -            // Locate every position with a 1
 | 
	
		
			
				|  |  | -            for pos in 0..self.board.width {
 | 
	
		
			
				|  |  | -                let cellindex = cellgroup[pos as usize];
 | 
	
		
			
				|  |  | -                /* 
 | 
	
		
			
				|  |  | -                let x = col + (pos % size);
 | 
	
		
			
				|  |  | -                let y = row + (pos / size);
 | 
	
		
			
				|  |  | -                */
 | 
	
		
			
				|  |  | -                // println!("Pos {} ({},{}) Value {}", pos, x, y, value);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                if self
 | 
	
		
			
				|  |  | -                    .possible
 | 
	
		
			
				|  |  | -                    .get(cellindex, value as usize + 1)
 | 
	
		
			
				|  |  | -                    // .get(self.possible.pos(x, y), value as usize + 1)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    // println!("Found {} ({},{}) = {}", cell_index, x, y, value);
 | 
	
		
			
				|  |  | -                    result[value as usize].set(pos as usize, true);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // Ok, this is good, but not useful.  ;)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        let zero_bits = GenBits::<u32>(0);
 | 
	
		
			
				|  |  | -        let width = self.board.width;
 | 
	
		
			
				|  |  | -        let mut possibles_updated : bool = false;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        'outer: for idx in 0..width-1 {
 | 
	
		
			
				|  |  | -            // pos_found contains the positions.
 | 
	
		
			
				|  |  | -            let pos_found = result[idx as usize]; 
 | 
	
		
			
				|  |  | -            if pos_found == zero_bits {
 | 
	
		
			
				|  |  | -                continue;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if idx > 0 {
 | 
	
		
			
				|  |  | -                // Check previous for matches - already checked...
 | 
	
		
			
				|  |  | -                for check in 0..idx {
 | 
	
		
			
				|  |  | -                    if pos_found == result[check as usize] {
 | 
	
		
			
				|  |  | -                        continue 'outer;
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            let count = pos_found.count_set();
 | 
	
		
			
				|  |  | -            if count == 1 {
 | 
	
		
			
				|  |  | -                // Single possible item here ... skip this for now.
 | 
	
		
			
				|  |  | -                continue;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            let mut matches = 1;
 | 
	
		
			
				|  |  | -            // Pos contains the numbers in the cell.
 | 
	
		
			
				|  |  | -            let mut pos = Vec::<u8>::new();
 | 
	
		
			
				|  |  | -            pos.push(idx);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            for look in idx+1..width {
 | 
	
		
			
				|  |  | -                if result[look as usize] == pos_found {
 | 
	
		
			
				|  |  | -                    matches += 1;
 | 
	
		
			
				|  |  | -                    pos.push(look);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if matches == count {
 | 
	
		
			
				|  |  | -                // Ok! We found a pair (or triple, or quad, or ...)
 | 
	
		
			
				|  |  | -                // Build new possible
 | 
	
		
			
				|  |  | -                let mut new_possible = zero_bits;
 | 
	
		
			
				|  |  | -                for p in &pos {
 | 
	
		
			
				|  |  | -                    new_possible.set(*p as usize, true);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                for p in pos_found.iter() {
 | 
	
		
			
				|  |  | -                    if self.possible.possible[cellgroup[p as usize]] != new_possible {
 | 
	
		
			
				|  |  | -                        println!("Update pos {} with {:?}", p, new_possible);
 | 
	
		
			
				|  |  | -                        println!("Index is {} => {:?}", cellgroup[p as usize], self.group.xy(cellgroup[p as usize]));
 | 
	
		
			
				|  |  | -                        possibles_updated = true;
 | 
	
		
			
				|  |  | -                        self.possible.possible[cellgroup[p as usize]] = new_possible;
 | 
	
		
			
				|  |  | -                        println!("Updated!");
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        result
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // find_pairs:  Finds the pairs (and triples, and quads, and ...) *MOVED to AnyPossible*
 | 
	
		
			
				|  |  |      /// Finalize move on the board.
 | 
	
		
			
				|  |  |      /// - This uses the cell index last modified, so we have fewer
 | 
	
		
			
				|  |  |      ///   cells to check here. (2 * size) cells.
 | 
	
	
		
			
				|  | @@ -830,85 +822,11 @@ impl AnySolver {
 | 
	
		
			
				|  |  |          let size = self.board.width;
 | 
	
		
			
				|  |  |          let mut update: bool = false;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        /* 
 | 
	
		
			
				|  |  | -        let values = self.find_pairs(index);
 | 
	
		
			
				|  |  | -        // ok! Scan, and find pairs, triples, etc.
 | 
	
		
			
				|  |  | -        println!("Finalize Cell {}: {:?}", index, values);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        'outer: for idx in 0..size-1 {
 | 
	
		
			
				|  |  | -            // Positions found
 | 
	
		
			
				|  |  | -            let pos_found = values[idx as usize];
 | 
	
		
			
				|  |  | -            if pos_found == (GenBits::<u32>(0)) {
 | 
	
		
			
				|  |  | -                println!("Idx {}: (empty)", idx);
 | 
	
		
			
				|  |  | -                continue;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if idx > 0 {
 | 
	
		
			
				|  |  | -                // check if previous done
 | 
	
		
			
				|  |  | -                for check in 0..idx {
 | 
	
		
			
				|  |  | -                    if pos_found == values[check as usize] {
 | 
	
		
			
				|  |  | -                        println!("Previously done {}  prev index {} {:?}", idx, check, pos_found);
 | 
	
		
			
				|  |  | -                        continue 'outer;
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            /*
 | 
	
		
			
				|  |  | -            if idx == size-2 {
 | 
	
		
			
				|  |  | -                break 'outer;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            // Check to see:
 | 
	
		
			
				|  |  | -            // - How many items are in it.
 | 
	
		
			
				|  |  | -            // - Can we find that many matches.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        /*
 | 
	
		
			
				|  |  | -            let count = pos_found.count_set();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if count == 1 {
 | 
	
		
			
				|  |  | -                // Or - should we process this single possible value here?
 | 
	
		
			
				|  |  | -                println!("Idx {}: has one item.", idx);
 | 
	
		
			
				|  |  | -                continue;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            let mut matches = 1;
 | 
	
		
			
				|  |  | -            let mut pos = Vec::<u8>::new();
 | 
	
		
			
				|  |  | -            pos.push(idx);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            println!("Starting at {}, we're looking for {:?} [{} times]", idx, pos_found, count);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            for look in idx+1..size {
 | 
	
		
			
				|  |  | -                if values[look as usize] == pos_found {
 | 
	
		
			
				|  |  | -                    matches += 1;
 | 
	
		
			
				|  |  | -                    pos.push(look);
 | 
	
		
			
				|  |  | -                    println!("Match found at {} ({} total)", look, matches);
 | 
	
		
			
				|  |  | -                } else {
 | 
	
		
			
				|  |  | -                    println!("{:?} did not match {:?} at {}", pos_found, values[look as usize], look);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            println!("Final {} matches found, looking for {}", matches, count);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if matches == count {
 | 
	
		
			
				|  |  | -                // Pair (or something) found!
 | 
	
		
			
				|  |  | -                println!("Pairs: {:?} [value {}]", values, idx);
 | 
	
		
			
				|  |  | -                println!("FOUND: Index {} Count {} Value {:?} {:?}", index, count, pos_found, pos);
 | 
	
		
			
				|  |  | -                // Ok! In this position, remove any other possible!
 | 
	
		
			
				|  |  | -                // What position am I talking about here?
 | 
	
		
			
				|  |  | -                // let index_pos = self.possible.which_cell_index(index, )
 | 
	
		
			
				|  |  | -            } else {
 | 
	
		
			
				|  |  | -                println!("missed: Index {} Count {} Value {:?} {:?}", index, count, pos_found, pos);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        */
 | 
	
		
			
				|  |  | +        self.possible.find_pairs(self.group.group(Groups::Cell, index));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        // println!("Pairs: {:?}", self.find_pairs(index));
 | 
	
		
			
				|  |  | +        // println!("Finalize Cell Pairs: {:?}", self.possible.find_pairs(self.group.group(Groups::Cell, index)));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        // Check columns
 | 
	
		
			
				|  |  | +        // Check columns - (of given cell) for logical removes (see logic_test for example)
 | 
	
		
			
				|  |  |          for c in 0..size {
 | 
	
		
			
				|  |  |              // Calculate the row and column for the given cell.
 | 
	
		
			
				|  |  |              let _col = (index % size) * size + c;
 | 
	
	
		
			
				|  | @@ -928,8 +846,8 @@ impl AnySolver {
 | 
	
		
			
				|  |  |      /// - This checks the board for logic fixes. (when column is full/has 1+pair/triple)
 | 
	
		
			
				|  |  |      pub fn finalize_move(&mut self) {
 | 
	
		
			
				|  |  |          // Process the cells diagonally.
 | 
	
		
			
				|  |  | -        println!("TODO");
 | 
	
		
			
				|  |  | -        /* 
 | 
	
		
			
				|  |  | +        println!("TODO: (finalize_move)");
 | 
	
		
			
				|  |  | +        /*
 | 
	
		
			
				|  |  |          for idx in 0..self.board.size {
 | 
	
		
			
				|  |  |              self.finalize_cell(idx + idx * self.board.size);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -1692,8 +1610,10 @@ mod tests {
 | 
	
		
			
				|  |  |             (3,7), (3,8) and (3,9) should not contain 2!
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        assert!(solver.validate_board());
 | 
	
		
			
				|  |  | +        solver.possible.display();
 | 
	
		
			
				|  |  | +        let pos_index = solver.group.pos(2,6);
 | 
	
		
			
				|  |  | +        assert_eq!(solver.possible.get(pos_index, 1), false, "(3,7) contains a 2  [{:?}](not possible)", solver.possible.possible[pos_index]);
 | 
	
		
			
				|  |  | +        // assert!(solver.validate_board());
 | 
	
		
			
				|  |  |          solver.possible.display();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /*
 | 
	
	
		
			
				|  | @@ -1722,6 +1642,71 @@ mod tests {
 | 
	
		
			
				|  |  |          println!("--- logic_test ---");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    #[ignore]
 | 
	
		
			
				|  |  | +    #[test]
 | 
	
		
			
				|  |  | +    fn try_this_out() {
 | 
	
		
			
				|  |  | +        let mut board = AnyBoard::new(3);
 | 
	
		
			
				|  |  | +        board.set(1, 0, 2);
 | 
	
		
			
				|  |  | +        board.set(2, 1, 3);
 | 
	
		
			
				|  |  | +        board.set(2, 2, 5);
 | 
	
		
			
				|  |  | +        board.set(1, 6, 3);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        board.set(0, 4, 4);
 | 
	
		
			
				|  |  | +        board.set(2, 4, 2);
 | 
	
		
			
				|  |  | +        board.set(3, 4, 3);
 | 
	
		
			
				|  |  | +        board.set(4, 4, 5);
 | 
	
		
			
				|  |  | +        board.set(5, 4, 7);
 | 
	
		
			
				|  |  | +        board.set(6, 4, 8);
 | 
	
		
			
				|  |  | +        board.set(7, 4, 9);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        board.set(1, 7, 5);
 | 
	
		
			
				|  |  | +        board.display();
 | 
	
		
			
				|  |  | +        let mut solver = AnySolver::new_from(&board);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        /*
 | 
	
		
			
				|  |  | +           ╔═══╦═══╦═══╗
 | 
	
		
			
				|  |  | +           ║ 2 ║   ║   ║
 | 
	
		
			
				|  |  | +           ║  3║   ║   ║
 | 
	
		
			
				|  |  | +           ║  5║   ║   ║
 | 
	
		
			
				|  |  | +           ╠═══╬═══╬═══╣
 | 
	
		
			
				|  |  | +           ║P  ║   ║   ║
 | 
	
		
			
				|  |  | +           ║4 2║357║89 ║
 | 
	
		
			
				|  |  | +           ║P  ║   ║   ║
 | 
	
		
			
				|  |  | +           ╠═══╬═══╬═══╣
 | 
	
		
			
				|  |  | +           ║ 3 ║   ║   ║
 | 
	
		
			
				|  |  | +           ║ 5 ║   ║   ║
 | 
	
		
			
				|  |  | +           ║   ║   ║   ║
 | 
	
		
			
				|  |  | +           ╚═══╩═══╩═══╝
 | 
	
		
			
				|  |  | +           P = Possible pair (3,5)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        (1,1):1,6,7,8,9         (2,1):                  (3,1):1,4,6,7,8,9       (4,1):1,3,4,5,6,7,8,9   (5,1):1,3,4,5,6,7,8,9   (6,1):1,3,4,5,6,7,8,9   (7,1):1,3,4,5,6,7,8,9   (8,1):1,3,4,5,6,7,8,9   (9,1):1,3,4,5,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,2):1,6,7,8,9         (2,2):1,4,6,7,8,9       (3,2):                  (4,2):1,2,4,5,6,7,8,9   (5,2):1,2,4,5,6,7,8,9   (6,2):1,2,4,5,6,7,8,9   (7,2):1,2,4,5,6,7,8,9   (8,2):1,2,4,5,6,7,8,9   (9,2):1,2,4,5,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,3):1,6,7,8,9         (2,3):1,4,6,7,8,9       (3,3):                  (4,3):1,2,3,4,6,7,8,9   (5,3):1,2,3,4,6,7,8,9   (6,3):1,2,3,4,6,7,8,9   (7,3):1,2,3,4,6,7,8,9   (8,3):1,2,3,4,6,7,8,9   (9,3):1,2,3,4,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,4):1,2,3,5,6,7,8,9   (2,4):1,6,7,8,9         (3,4):1,2,6,7,8,9       (4,4):1,2,3,4,5,6,7,8,9 (5,4):1,2,3,4,5,6,7,8,9 (6,4):1,2,3,4,5,6,7,8,9 (7,4):1,2,3,4,5,6,7,8,9 (8,4):1,2,3,4,5,6,7,8,9 (9,4):1,2,3,4,5,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,5):                  (2,5):1,6,7,8,9         (3,5):1,2,6,7,8,9       (4,5):1,2,3,5,6,7,8,9   (5,5):1,2,3,5,6,7,8,9   (6,5):1,2,3,5,6,7,8,9   (7,5):1,2,3,5,6,7,8,9   (8,5):1,2,3,5,6,7,8,9   (9,5):1,2,3,5,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,6):1,2,3,5,6,7,8,9   (2,6):1,6,7,8,9         (3,6):1,2,6,7,8,9       (4,6):1,2,3,4,5,6,7,8,9 (5,6):1,2,3,4,5,6,7,8,9 (6,6):1,2,3,4,5,6,7,8,9 (7,6):1,2,3,4,5,6,7,8,9 (8,6):1,2,3,4,5,6,7,8,9 (9,6):1,2,3,4,5,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,7):1,2,6,7,8,9       (2,7):                  (3,7):1,2,4,6,7,8,9     (4,7):1,2,4,5,6,7,8,9   (5,7):1,2,4,5,6,7,8,9   (6,7):1,2,4,5,6,7,8,9   (7,7):1,2,4,5,6,7,8,9   (8,7):1,2,4,5,6,7,8,9   (9,7):1,2,4,5,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,8):1,2,6,7,8,9       (2,8):                  (3,8):1,2,4,6,7,8,9     (4,8):1,2,3,4,6,7,8,9   (5,8):1,2,3,4,6,7,8,9   (6,8):1,2,3,4,6,7,8,9   (7,8):1,2,3,4,6,7,8,9   (8,8):1,2,3,4,6,7,8,9   (9,8):1,2,3,4,6,7,8,9
 | 
	
		
			
				|  |  | +        (1,9):1,2,6,7,8,9       (2,9):1,4,6,7,8,9       (3,9):1,2,4,6,7,8,9     (4,9):1,2,3,4,5,6,7,8,9 (5,9):1,2,3,4,5,6,7,8,9 (6,9):1,2,3,4,5,6,7,8,9 (7,9):1,2,3,4,5,6,7,8,9 (8,9):1,2,3,4,5,6,7,8,9 (9,9):1,2,3,4,5,6,7,8,9
 | 
	
		
			
				|  |  | +        ^ This shows the logic bug.
 | 
	
		
			
				|  |  | +          (1,4) and (1,6) should only be 3,5.
 | 
	
		
			
				|  |  | +          (3,7), (3,8), and (3,9) should not contain 2.
 | 
	
		
			
				|  |  | +        */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        println!("RIGHT HERE:");
 | 
	
		
			
				|  |  | +        /*
 | 
	
		
			
				|  |  | +        let g= solver.group.group(Groups::Cell, 3); 
 | 
	
		
			
				|  |  | +        let pairs = solver.possible.find_pairs(g);
 | 
	
		
			
				|  |  | +        */
 | 
	
		
			
				|  |  | +        let pairs = solver.possible.find_pairs(solver.group.group(Groups::Cell, 3));
 | 
	
		
			
				|  |  | +        println!("Pairs [cell index 3]: {:?}", pairs);
 | 
	
		
			
				|  |  | +        let g= solver.group.group(Groups::Row, 4); // .clone();
 | 
	
		
			
				|  |  | +        let pairs = solver.possible.find_pairs(g);
 | 
	
		
			
				|  |  | +        println!("Pairs [ row index 4]: {:?}", pairs);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        solver.finalize_cell(3);
 | 
	
		
			
				|  |  | +        solver.possible.display();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      #[ignore]
 | 
	
		
			
				|  |  |      #[test]
 | 
	
		
			
				|  |  |      fn logic_test_pairs() {
 | 
	
	
		
			
				|  | @@ -1765,7 +1750,8 @@ mod tests {
 | 
	
		
			
				|  |  |          */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          println!("RIGHT HERE:");
 | 
	
		
			
				|  |  | -        println!("Pairs [cell index 3]: {:?}", solver.find_pairs(3));
 | 
	
		
			
				|  |  | +        let g= solver.group.group(Groups::Cell, 3);
 | 
	
		
			
				|  |  | +        println!("Pairs [cell index 3]: {:?}", solver.possible.find_pairs( g));
 | 
	
		
			
				|  |  |          solver.finalize_cell(3);
 | 
	
		
			
				|  |  |          solver.possible.display();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1775,7 +1761,7 @@ mod tests {
 | 
	
		
			
				|  |  |           */
 | 
	
		
			
				|  |  |          // Is validate_board destroying our work?!?
 | 
	
		
			
				|  |  |          // YES IT IS!
 | 
	
		
			
				|  |  | -        assert!(solver.validate_board());
 | 
	
		
			
				|  |  | +        // assert!(solver.validate_board());
 | 
	
		
			
				|  |  |          solver.possible.display();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 |