Browse Source

Working AnyPossible.find_pairs.

This "works/can be called" with cells, rows, and columns.
Steve Thielemann 3 tháng trước cách đây
mục cha
commit
01338576eb
1 tập tin đã thay đổi với 175 bổ sung189 xóa
  1. 175 189
      sudoku/src/sudoku.rs

+ 175 - 189
sudoku/src/sudoku.rs

@@ -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();
     }