Prechádzať zdrojové kódy

Added AnyPossible display.

Steve Thielemann 3 mesiacov pred
rodič
commit
1d2925d072
2 zmenil súbory, kde vykonal 122 pridanie a 147 odobranie
  1. 7 0
      sudoku/src/bits.rs
  2. 115 147
      sudoku/src/sudoku.rs

+ 7 - 0
sudoku/src/bits.rs

@@ -37,6 +37,13 @@ impl<T: Integer + BitField> GenBits<T> {
         }
         count
     }
+
+    pub fn display(&self) -> String {
+        self.iter()
+            .map(|i| (i+1).to_string())
+            .collect::<Vec<_>>().join(",")
+    }
+
 }
 
 pub struct GenBitsIterator<'a, T: Integer + BitField> {

+ 115 - 147
sudoku/src/sudoku.rs

@@ -606,22 +606,48 @@ impl AnyPossible {
         )
     }
 
+    /*
+    How can I find the max size of each display possible item?
+    I'd like to cache the info so I don't re-calc it, and I'd like a pony! :P
+
+     */
+
+    /// Format all possible, finding max length.
+    pub fn pos_max(&self) -> (Vec<String>, usize) {
+        let mut pos = Vec::<String>::new();
+        pos.reserve(self.max_index);
+        let mut max: usize = 0;
+
+        for idx in 0..self.max_index {
+            let s = self.possible[idx].display();
+            if max < s.len() {
+                max = s.len();
+            }
+            pos.push(s);
+        }
+        (pos, max)
+    }
+
     pub fn display(&self) {
+        let pos_info = self.pos_max();
+
         for y in 0..self.width {
             for x in 0..self.width {
                 let idx = self.pos(x, y);
+
+                /* 
                 let possible = self.possible[idx];
                 let values: Vec<u8> = possible.iter().collect();
                 // let stuff: String = values.into_iter().map(|i| i.to_string().push_str(",")).collect::<String>();
+                // let output = values.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
+
                 let stuff: String = values
                     .into_iter()
                     .map(|i| (i + 1).to_string())
-                    .collect::<String>();
-                /*
-                if stuff.len() > 1 {
-                    stuff.pop();
-                }*/
-                print!("({},{}):{:9} ", x + 1, y + 1, stuff);
+                    // .collect::<String>();
+                    .collect::<Vec<_>>().join(",");
+                */
+                print!("({},{}):{:3$} ", x + 1, y + 1, pos_info.0[idx], pos_info.1);
             }
             println!("");
         }
@@ -868,7 +894,8 @@ impl AnySolver {
     /// - Call solve until it returns false.
     /// - It might not be solved (if guessing is required).
     pub fn solve_logic(&mut self) -> bool {
-        self.reset_possible();
+        // self.reset_possible(); // destroys anything pass3 accomplishes ...
+
         // self.board.display();
         // self.possible.display();
 
@@ -913,7 +940,19 @@ impl AnySolver {
                 // Nothing found with this run of pass 1.
 
                 // Pass 2 - Look for singles within the groups.
-                
+
+                // Are we done?
+                /*
+                if self.board.complete() {
+                    return false;
+                }
+                // We're getting stuck in pass 2 ...
+                // not anymore.  ;)
+                println!("Pass 2:");
+                self.board.display();
+
+                */
+
                 found_something = false;
 
                 let mut values = Bits(0); // HashSet<u8> = HashSet::new();
@@ -929,16 +968,16 @@ impl AnySolver {
                         // 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() {
                         // println!("Check Value: {}", v);
-        
+
                         let mut count = 0;
                         let mut pos = 0;
-        
+
                         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) {
@@ -957,14 +996,14 @@ impl AnySolver {
                             let xy = this.board.xy(pos);
                             // this.possible.display();
                             // this.board.display();
-                            this.set(xy.0, xy.1, v+1);
+                            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}:");
@@ -976,8 +1015,8 @@ impl AnySolver {
                     // println!("Cell {i}:");
                     g = grp.cell(i);
                     group_process(self, g);
-                }        
-        
+                }
+
                 if found_something == true {
                     pass2 = true;
                     // Ok, pass 2 found something.
@@ -992,180 +1031,107 @@ impl AnySolver {
                 if pass1 {
                     pass1_again = false;
                     found_something = true;
+                } else {
+                    // Ok, we didn't find anything.
+                    // Break out of loop, get unstuck.
+                    break;
                 }
             }
         }
 
-        // After changing Pass1 to loop, I don't think I need to go over the
-        // groups now.  Besides, possible should be covering all the groups
-        // anyway!
-
-        /*
-        println!("Set2:");
-        self.board.display();
-        self.possible.display();
-        */
-
-        // This is a mess here.  It looks obsoleted by the above pass1 loop.
+        // Pass 3:
+        // - Find pairs & remove those numbers from corresponding group.
 
-        // No, it isn't.
-
-        /*
- Set2:
-╔═══╦═══╦═══╗
-║  1║7 8║3  ║
-║ 73║   ║68 ║
-║286║934║751║
-╠═══╬═══╬═══╣
-║   ║1 7║   ║
-║ 2 ║   ║ 9 ║
-║ 14║   ║86 ║
-╠═══╬═══╬═══╣
-║  8║3 1║9  ║
-║   ║   ║   ║
-║432║879║516║
-╚═══╩═══╩═══╝
-(1,1):59        (2,1):459       (3,1):          (4,1):          (5,1):256       (6,1):          (7,1):          (8,1):24        (9,1):249       
-(1,2):59        (2,2):          (3,2):          (4,2):25        (5,2):125       (6,2):25        (7,2):          (8,2):          (9,2):249       
-(1,3):          (2,3):          (3,3):          (4,3):          (5,3):          (6,3):          (7,3):          (8,3):          (9,3):          
-(1,4):35689     (2,4):569       (3,4):59        (4,4):          (5,4):245689    (6,4):          (7,4):24        (8,4):234       (9,4):2345      
-(1,5):35678     (2,5):          (3,5):57        (4,5):456       (5,5):4568      (6,5):356       (7,5):14        (8,5):          (9,5):3457      
-(1,6):3579      (2,6):          (3,6):          (4,6):25        (5,6):259       (6,6):235       (7,6):          (8,6):          (9,6):2357      
-(1,7):567       (2,7):56        (3,7):          (4,7):          (5,7):2456      (6,7):          (7,7):          (8,7):247       (9,7):247       
-(1,8):15679     (2,8):569       (3,8):579       (4,8):2456      (5,8):2456      (6,8):256       (7,8):24        (8,8):2347      (9,8):23478     
-(1,9):          (2,9):          (3,9):          (4,9):          (5,9):          (6,9):          (7,9):          (8,9):          (9,9):          
-
-        See:  
-        (2,1) only has a 4 in cell/column.
-        (5,2) only has a 1 in cell.
-        (7,5) only has a 1 in column.
-        (1,8) only has a 1 (rows/column).
-        (9,8) only has 8.
-         */
-
-        /* 
-        let width = self.group.width;
         let grp = self.group.clone();
-        let mut values = Bits(0); // HashSet<u8> = HashSet::new();
-
-        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, 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() {
-                println!("Check Value: {}", v);
-
-                let mut count = 0;
-                let mut pos = 0;
-
-                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);
-                    println!("SET {} ({},{}) = {}", pos, xy.0 + 1, xy.1 + 1, v);
-
-                    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 {
-            return found_something;
-        }
-        */
-        return false;
-        
+        println!("Pass 3:");
+        self.board.display();
+        self.possible.display();
 
-        let width = self.group.width;
-        let grp = self.group.clone();
+        assert_eq!(self.board.width, self.possible.width);
 
         // Pair processing.
         for i in 0..width {
             let mut g = grp.cell(i);
+            println!("Cell {}: {:?}", i, g);
 
             for gidx in 0..WIDTH - 1 {
                 let gpos = g[gidx as usize];
-                if self.possible.possible[gpos as usize].count_set() == 2 {
+                if self.possible.possible[gpos].count_set() == 2 {
                     // Found a pair
+
                     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])
-                            if self.possible.possible[gpos] == self.possible.possible[fpos as usize]
-                            {
+
+                            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!
+
+                                // This looks .. WRONG!  only z+1 when using set(value)!
+
                                 let mut values: [u8; 2] = [0, 0];
                                 let mut vpos = 0;
                                 for z in self.possible.possible[gpos].iter() {
-                                    values[vpos] = z + 1;
+                                    values[vpos] = z;
                                     vpos += 1;
                                 }
 
+                                // Ok, other then being off by 1 (because x,y starts at 0 not 1),
+                                // This is, at least, displaying the information properly.
+
+                                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
+                                );
+
                                 let mut pair_removed = false;
 
                                 // 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;
                                     }
+
                                     // 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[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 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
+                                    );
+                                }
+
                                 // 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
@@ -1232,27 +1198,28 @@ impl AnySolver {
                                     }
                                 }
 
-                                /*
                                 if pair_removed {
-                                    if debug {
+                                    if true {
                                         println!(
                                             "Pair found! {} {}: {} {:?} and {} {:?} !",
                                             gidx,
                                             fidx,
                                             gpos,
-                                            xy(gpos),
+                                            self.board.xy(gpos),
                                             fpos,
-                                            xy(fpos)
+                                            self.board.xy(fpos)
                                         );
+                                        self.possible.display();
+                                        // panic!("... We're lost ...");
                                     }
                                 }
-                                */
                             }
                         }
                     }
                 }
             }
         }
+        println!("Pass 3 - Ending...");
         found_something
     }
 }
@@ -1290,13 +1257,14 @@ mod tests {
         // board.display();
         let mut solver = AnySolver::new_from(&board);
         assert!(solver.validate_board());
-        
+
+        solver.reset_possible();
         // solver.solve_logic();
-        
+
         while (solver.solve_logic()) {
             solver.board.display();
         }
-        
+
         assert!(solver.validate_board());
         assert!(solver.board.complete());
 
@@ -1334,7 +1302,7 @@ mod tests {
         while (solver.solve_logic()) {
             solver.board.display();
         }
-        
+
         assert!(solver.validate_board());
         solver.board.display();
         assert!(solver.board.complete());