|  | @@ -613,6 +613,8 @@ impl AnyPossible {
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Format all possible, finding max length.
 | 
	
		
			
				|  |  | +    /// - Return vec<string> of each item formatted.
 | 
	
		
			
				|  |  | +    /// - Return max length.
 | 
	
		
			
				|  |  |      pub fn pos_max(&self) -> (Vec<String>, usize) {
 | 
	
		
			
				|  |  |          let mut pos = Vec::<String>::new();
 | 
	
		
			
				|  |  |          pos.reserve(self.max_index);
 | 
	
	
		
			
				|  | @@ -628,6 +630,9 @@ impl AnyPossible {
 | 
	
		
			
				|  |  |          (pos, max)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /// Display Possible
 | 
	
		
			
				|  |  | +    /// - Collect all of the possibles, with max length.
 | 
	
		
			
				|  |  | +    /// - Display formatted (using max length).
 | 
	
		
			
				|  |  |      pub fn display(&self) {
 | 
	
		
			
				|  |  |          let pos_info = self.pos_max();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -635,18 +640,6 @@ impl AnyPossible {
 | 
	
		
			
				|  |  |              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>();
 | 
	
		
			
				|  |  | -                    .collect::<Vec<_>>().join(",");
 | 
	
		
			
				|  |  | -                */
 | 
	
		
			
				|  |  |                  print!("({},{}):{:3$} ", x + 1, y + 1, pos_info.0[idx], pos_info.1);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              println!("");
 | 
	
	
		
			
				|  | @@ -889,6 +882,132 @@ impl AnySolver {
 | 
	
		
			
				|  |  |          true
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    fn logic_pass1(&mut self) -> bool {
 | 
	
		
			
				|  |  | +        // Pass 1: Look for singles in the possible sets.
 | 
	
		
			
				|  |  | +        let mut pass1 = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Repeat pass 1 until all have been found.
 | 
	
		
			
				|  |  | +        let mut pass1_again = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        while pass1_again {
 | 
	
		
			
				|  |  | +            // Pass 1 - look for singles.
 | 
	
		
			
				|  |  | +            pass1_again = false;
 | 
	
		
			
				|  |  | +            let mut found_something = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            for i in 0..self.possible.max_index {
 | 
	
		
			
				|  |  | +                if self.board.board[i] != 0 {
 | 
	
		
			
				|  |  | +                    // Skip, if position already filled.
 | 
	
		
			
				|  |  | +                    continue;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                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;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if found_something {
 | 
	
		
			
				|  |  | +                // We found something on this pass, so:
 | 
	
		
			
				|  |  | +                // - Try it again.
 | 
	
		
			
				|  |  | +                // - Record that we did something.
 | 
	
		
			
				|  |  | +                pass1 = true;
 | 
	
		
			
				|  |  | +                pass1_again = true;
 | 
	
		
			
				|  |  | +                found_something = false;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pass1
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    fn logic_pass2(&mut self) -> bool {
 | 
	
		
			
				|  |  | +        let mut found_something = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let mut pass2 = false;
 | 
	
		
			
				|  |  | +        let mut pass2_again = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let width = self.group.width;
 | 
	
		
			
				|  |  | +        let grp = self.group.clone();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        while pass2_again {
 | 
	
		
			
				|  |  | +            pass2_again = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 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 {
 | 
	
		
			
				|  |  | +                    // 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]);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // 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 + 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 {
 | 
	
		
			
				|  |  | +                // Ok, pass 2 found something.
 | 
	
		
			
				|  |  | +                pass2 = true;                
 | 
	
		
			
				|  |  | +                found_something = false;
 | 
	
		
			
				|  |  | +                pass2_again = true;
 | 
	
		
			
				|  |  | +                // continue;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pass2
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /// Solve by logic alone.
 | 
	
		
			
				|  |  |      /// - Returns true when something was added to board.
 | 
	
		
			
				|  |  |      /// - Call solve until it returns false.
 | 
	
	
		
			
				|  | @@ -898,8 +1017,24 @@ impl AnySolver {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 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");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        result || result2
 | 
	
		
			
				|  |  | +        /*
 | 
	
		
			
				|  |  | +        // Pass 2: Is the same as Pass 1!
 | 
	
		
			
				|  |  | +        // We just look in groups, instead of all the indexes.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          let mut found_something = false;
 | 
	
		
			
				|  |  |          let mut pass1 = false;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1222,6 +1357,7 @@ impl AnySolver {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          println!("Pass 3 - Ending...");
 | 
	
		
			
				|  |  |          found_something
 | 
	
		
			
				|  |  | +        */
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |