Steve Thielemann 1 mês atrás
pai
commit
29e635c3a5
4 arquivos alterados com 157 adições e 27 exclusões
  1. 6 0
      Cargo.toml
  2. 7 0
      sudoku/Cargo.toml
  3. 3 0
      sudoku/src/group.rs
  4. 141 27
      sudoku/src/sudoku.rs

+ 6 - 0
Cargo.toml

@@ -17,3 +17,9 @@ sudoku = { path = "sudoku" }
 # name = "benchmark"
 # harness = false
 
+[source.crates-io]
+replace-with = "vendored-sources"
+
+[source.vendored-sources]
+directory = "vendor"
+

+ 7 - 0
sudoku/Cargo.toml

@@ -17,3 +17,10 @@ xml = "0.8.20"
 [lib]
 name = "sudoku"
 test = true
+
+[source.crates-io]
+replace-with = "vendored-sources"
+
+[source.vendored-sources]
+directory = "vendor"
+

+ 3 - 0
sudoku/src/group.rs

@@ -131,6 +131,9 @@ impl AnyGroup {
     /// Return index of cell (x,y)
     /// - This uses the groups to locate the index of the group.
     pub fn cell_index(&self, index: u8, x: u8, y: u8) -> usize {
+        debug_assert!( x < self.size);
+        debug_assert!( y < self.size);
+        
         let result: usize =
             self.groups[Groups::Cell as usize][index as usize * self.width as usize];
         result + (y * self.width + x) as usize

+ 141 - 27
sudoku/src/sudoku.rs

@@ -553,7 +553,6 @@ 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).
@@ -599,20 +598,24 @@ impl AnyPossible {
             }
 
             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 count != 1 {
+                for look in idx + 1..width {
+                    if result[look as usize] == pos_found {
+                        matches += 1;
+                        pos.push(look);
+                    }
                 }
             }
 
@@ -629,7 +632,7 @@ impl AnyPossible {
                     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],
@@ -648,7 +651,6 @@ impl AnyPossible {
         (pairs, possibles_updated)
     }
 
-
     /// Display Possible
     /// - Collect all of the possibles, with max length.
     /// - Display formatted (using max length).
@@ -678,16 +680,19 @@ yet another.  I think that's how I mentally judge the puzzles.
 
  */
 
+/*
 pub struct Pairs {
     pub values: [u8; 2],
     pub pos: [u8; 2],
 }
+*/
 
 #[derive(Debug, Clone)]
 pub struct AnySolver {
     pub board: AnyBoard,
     pub possible: AnyPossible,
     pub group: AnyGroup,
+    // Is this value set in the given cell?
     pub cell_poss: Vec<GenBits<u32>>,
 }
 
@@ -813,31 +818,126 @@ impl AnySolver {
 
         // OR, just check row and columns?
     }
-    
+
+    pub fn finalize_possible(&mut self) {
+        let width = self.board.width;
+        let size = self.board.size;
+
+        // I might want to save the pair information.
+
+        for cell in 0..width {
+            self.possible
+                .find_pairs(self.group.group(Groups::Cell, cell));
+        }
+
+        // What values are possible in which rows/columns and cells?
+        
+        // Scan rows/columns
+        for cell in 0..width {
+            let cell_info = self.group.group(Groups::Cell, cell);
+
+            for row in 0..size {
+
+            }
+        }
+    }
+
     // 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.
-    pub fn finalize_cell(&mut self, index: u8) {
-        let size = self.board.width;
+    #[deprecated]
+    pub fn finalize_cell(&mut self, cell_index: u8) {
+        let width = self.board.width;
+        let size = self.board.size;
         let mut update: bool = false;
 
-        self.possible.find_pairs(self.group.group(Groups::Cell, index));
+        self.possible
+            .find_pairs(self.group.group(Groups::Cell, cell_index));
 
         // println!("Finalize Cell Pairs: {:?}", self.possible.find_pairs(self.group.group(Groups::Cell, index)));
 
+        /*
+        Let me describe what I want to do here:
+
+        ╔═══╦═══╦═══╗
+        ║ 2 ║   ║   ║
+        ║   ║   ║   ║
+        ║   ║   ║   ║
+        ╠═══╬═══╬═══╣
+        ║3  ║   ║   ║
+        ║4  ║   ║   ║
+        ║5  ║   ║   ║
+        ╠═══╬═══╬═══╣
+        ║   ║   ║   ║
+        ║   ║   ║   ║
+        ║   ║   ║   ║
+        ╚═══╩═══╩═══╝
+        (1,1):1,6,7,8,9         (2,1):                  (3,1):1,3,4,5,6,7,8,9
+        (1,2):1,6,7,8,9         (2,2):1,3,4,5,6,7,8,9   (3,2):1,3,4,5,6,7,8,9
+        (1,3):1,6,7,8,9         (2,3):1,3,4,5,6,7,8,9   (3,3):1,3,4,5,6,7,8,9
+        (1,4):                  (2,4):1,6,7,8,9         (3,4):1,2,6,7,8,9
+        (1,5):                  (2,5):1,6,7,8,9         (3,5):1,2,6,7,8,9
+        (1,6):                  (2,6):1,6,7,8,9         (3,6):1,2,6,7,8,9
+        (1,7):1,2,6,7,8,9       (2,7):1,3,4,5,6,7,8,9   (3,7):1,2,3,4,5,6,7,8,9
+        (1,8):1,2,6,7,8,9       (2,8):1,3,4,5,6,7,8,9   (3,8):1,2,3,4,5,6,7,8,9
+        (1,9):1,2,6,7,8,9       (2,9):1,3,4,5,6,7,8,9   (3,9):1,2,3,4,5,6,7,8,9
+
+        In cell 3, 2 must be in the last column.
+        In cell 6, 2 must be in the first column.  (3,7), (3,8) and (3,9) should not contain 2.
+
+         */
+        let (cell_x, cell_y) = self.group.xy(self.group.group(Groups::Cell, cell_index)[0]);
+        let x_range = cell_x..cell_x + self.board.size;
+        let y_range = cell_y..cell_y + self.board.size;
+        let top_cell = cell_index - (cell_index / size) * size;
+        let left_cell = cell_index - (cell_index % size);
+
+        println!(
+            "finalize_cell({cell_index}): ({cell_x},{cell_y}) top {top_cell} left {left_cell}"
+        );
+
+        // Ranges are consumed.
+
         // 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;
-            // println!("Index {} COL {}", index, col);
+        for value in 0..width {
+            // Find what columns value is allowed. (in which cells).
+            // Is this value needed in any of the cells?
+            let mut found = GenBits::<u32>(0);
+            let mut all_cells = found;
+
+            for ci in (top_cell..width).step_by(size as usize) {
+                all_cells.set(ci as usize, true);
+                if self.cell_poss[ci as usize].get(value as usize) {
+                    found.set(ci as usize, true);
+                }
+            }
+
+            if found == GenBits::<u32>(0) {
+                // Not possible anywhere, so skip to next value.
+                continue;
+            }
+
+            println!("Value {} {:?} is needed {:?}", value + 1, all_cells, found);
+
+            for x in x_range.clone() {
+                for y in 0..width {
+                    // Calculate the row and column for the given cell.
+                    // let _col = (cell_index % width) * width + c;
+                    // println!("Index {} COL {}", index, col);
+                }
+            }
         }
 
         // Check rows
-        for r in 0..size {
-            // Calculate the row and column for the given cell.
-            let _row = (index / size) * size + r;
-            // println!("Index {} ROW {}", index, row);
+        for value in 0..width {
+            for y in y_range.clone() {
+                for x in 0..width {
+                    // Calculate the row and column for the given cell.
+                    // let _row = (cell_index / width) * width + r;
+                    // println!("Index {} ROW {}", index, row);
+                }
+            }
         }
         println!("finalize_cell ends...");
     }
@@ -846,7 +946,13 @@ 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: (finalize_move)");
+        println!("TODO: (naively)");
+
+        // naive solution - check all the cells.
+        for idx in 0..self.board.width {
+            self.finalize_cell(idx);
+        }
+
         /*
         for idx in 0..self.board.size {
             self.finalize_cell(idx + idx * self.board.size);
@@ -1611,8 +1717,13 @@ mod tests {
 
         */
         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]);
+        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();
 
@@ -1662,6 +1773,7 @@ mod tests {
         board.set(1, 7, 5);
         board.display();
         let mut solver = AnySolver::new_from(&board);
+        solver.possible.display();
 
         /*
            ╔═══╦═══╦═══╗
@@ -1695,12 +1807,14 @@ mod tests {
 
         println!("RIGHT HERE:");
         /*
-        let g= solver.group.group(Groups::Cell, 3); 
+        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));
+        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 g = solver.group.group(Groups::Row, 4); // .clone();
         let pairs = solver.possible.find_pairs(g);
         println!("Pairs [ row index 4]: {:?}", pairs);
 
@@ -1750,8 +1864,8 @@ mod tests {
         */
 
         println!("RIGHT HERE:");
-        let g= solver.group.group(Groups::Cell, 3);
-        println!("Pairs [cell index 3]: {:?}", solver.possible.find_pairs( g));
+        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();