|  | @@ -445,7 +445,7 @@ impl AnyBoard {
 | 
	
		
			
				|  |  |          solutions.reserve(max as usize);
 | 
	
		
			
				|  |  |          workset.brute_force(&mut total_solutions, &mut solutions, &groups);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        /* 
 | 
	
		
			
				|  |  | +        /*
 | 
	
		
			
				|  |  |          if solutions.len() > 0 {
 | 
	
		
			
				|  |  |              println!("*** A Solution:");
 | 
	
		
			
				|  |  |              solutions[0].display();
 | 
	
	
		
			
				|  | @@ -694,20 +694,21 @@ impl AnySolver {
 | 
	
		
			
				|  |  |          );
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          let mut g = self.group.row(y);
 | 
	
		
			
				|  |  | -        let value: usize = value as usize;
 | 
	
		
			
				|  |  | +        let val: usize = value as usize;
 | 
	
		
			
				|  |  |          for g in g {
 | 
	
		
			
				|  |  | -            self.possible.set(*g, value, false);
 | 
	
		
			
				|  |  | +            self.possible.set(*g, val, false);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          g = self.group.column(x);
 | 
	
		
			
				|  |  |          for g in g {
 | 
	
		
			
				|  |  | -            self.possible.set(*g, value, false);
 | 
	
		
			
				|  |  | +            self.possible.set(*g, val, false);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          g = self.group.cell(self.group.which_cell(x, y));
 | 
	
		
			
				|  |  |          for g in g {
 | 
	
		
			
				|  |  | -            self.possible.set(*g, value, false);
 | 
	
		
			
				|  |  | +            self.possible.set(*g, val, false);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          let idx = self.possible.pos(x, y);
 | 
	
		
			
				|  |  |          self.possible.possible[idx] = GenBits::<u32>(0); // .clear();
 | 
	
		
			
				|  |  | +        self.board.board[idx] = value;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Validate the board
 | 
	
	
		
			
				|  | @@ -867,23 +868,182 @@ 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.board.display();
 | 
	
		
			
				|  |  | +        // self.possible.display();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          // Pass 1: Look for singles in the possible sets.
 | 
	
		
			
				|  |  |          let mut found_something = false;
 | 
	
		
			
				|  |  | +        let mut pass1 = false;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        for i in 0 .. self.possible.max_index {
 | 
	
		
			
				|  |  | -            if self.board.board[i] != 0 {
 | 
	
		
			
				|  |  | -                // Skip, if position already filled.
 | 
	
		
			
				|  |  | -                continue;
 | 
	
		
			
				|  |  | +        // Repeat pass 1 until all have been found.
 | 
	
		
			
				|  |  | +        let mut pass1_again = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let width = self.group.width;
 | 
	
		
			
				|  |  | +        let grp = self.group.clone();
 | 
	
		
			
				|  |  | +        let mut pass2 = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        while pass1_again {
 | 
	
		
			
				|  |  | +            // Pass 1 - look for singles.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            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 self.possible.possible[i].count_set() == 1 {
 | 
	
		
			
				|  |  | -                // Get value
 | 
	
		
			
				|  |  | -                let value = self.possible.possible[i].iter().next().unwrap();
 | 
	
		
			
				|  |  | -                let pos = self.board.xy(i);
 | 
	
		
			
				|  |  | -                self.set(pos.0, pos.1, value);
 | 
	
		
			
				|  |  | -                found_something = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if found_something {
 | 
	
		
			
				|  |  | +                // We found something this pass.
 | 
	
		
			
				|  |  | +                // - set pass1 to true (pass 1 found something)
 | 
	
		
			
				|  |  | +                // - reset found_something so we can try again.
 | 
	
		
			
				|  |  | +                pass1 = true;
 | 
	
		
			
				|  |  | +                found_something = false;
 | 
	
		
			
				|  |  | +                continue;
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                // Nothing found with this run of pass 1.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // Pass 2 - Look for singles within the groups.
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +                found_something = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                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+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 {
 | 
	
		
			
				|  |  | +                    pass2 = true;
 | 
	
		
			
				|  |  | +                    // Ok, pass 2 found something.
 | 
	
		
			
				|  |  | +                    found_something = false;
 | 
	
		
			
				|  |  | +                    continue;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                //
 | 
	
		
			
				|  |  | +                // - If pass1 set, reset the found_something (because it
 | 
	
		
			
				|  |  | +                //   did find something)
 | 
	
		
			
				|  |  | +                // - Clear the pass1_again flag, we're done with pass 1.
 | 
	
		
			
				|  |  | +                if pass1 {
 | 
	
		
			
				|  |  | +                    pass1_again = false;
 | 
	
		
			
				|  |  | +                    found_something = true;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        // 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.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 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();
 | 
	
	
		
			
				|  | @@ -900,32 +1060,36 @@ impl AnySolver {
 | 
	
		
			
				|  |  |                  // println!("now     : {:?}", this.possible[grp.items[gidx as usize] as usize]);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // println!("values {:?}", values);
 | 
	
		
			
				|  |  | +            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) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                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();
 | 
	
		
			
				|  |  | -                    /*
 | 
	
		
			
				|  |  | -                    if debug {
 | 
	
		
			
				|  |  | -                        println!("Set2 {:?} to {}", xy(pos), v);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    */
 | 
	
		
			
				|  |  |                      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;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -933,10 +1097,13 @@ impl AnySolver {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 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);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -944,9 +1111,148 @@ impl AnySolver {
 | 
	
		
			
				|  |  |          if found_something {
 | 
	
		
			
				|  |  |              return found_something;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        */
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let width = self.group.width;
 | 
	
		
			
				|  |  | +        let grp = self.group.clone();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // Pair processing.
 | 
	
		
			
				|  |  | +        for i in 0..width {
 | 
	
		
			
				|  |  | +            let mut g = grp.cell(i);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            for gidx in 0..WIDTH - 1 {
 | 
	
		
			
				|  |  | +                let gpos = g[gidx as usize];
 | 
	
		
			
				|  |  | +                if self.possible.possible[gpos as usize].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]
 | 
	
		
			
				|  |  | +                            {
 | 
	
		
			
				|  |  | +                                // 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!
 | 
	
		
			
				|  |  | +                                let mut values: [u8; 2] = [0, 0];
 | 
	
		
			
				|  |  | +                                let mut vpos = 0;
 | 
	
		
			
				|  |  | +                                for z in self.possible.possible[gpos].iter() {
 | 
	
		
			
				|  |  | +                                    values[vpos] = z + 1;
 | 
	
		
			
				|  |  | +                                    vpos += 1;
 | 
	
		
			
				|  |  | +                                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                let mut pair_removed = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                // Check to see if anything was removed.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                for remove in 0..width {
 | 
	
		
			
				|  |  | +                                    if (gidx == remove) || (fidx == remove) {
 | 
	
		
			
				|  |  | +                                        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;
 | 
	
		
			
				|  |  | +                                    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                    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;
 | 
	
		
			
				|  |  | +                                    }
 | 
	
		
			
				|  |  | +                                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                // 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
 | 
	
		
			
				|  |  | +                                    let column = xy(gpos).0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                    vpos = 0;
 | 
	
		
			
				|  |  | +                                    for z in self.possible.possible[gpos].iter() {
 | 
	
		
			
				|  |  | +                                        values[vpos] = z + 1;
 | 
	
		
			
				|  |  | +                                        vpos += 1;
 | 
	
		
			
				|  |  | +                                    }
 | 
	
		
			
				|  |  | +                                    for remove in 0..WIDTH {
 | 
	
		
			
				|  |  | +                                        if (remove == xy(gpos).1) || (remove == xy(fpos).1) {
 | 
	
		
			
				|  |  | +                                            continue;
 | 
	
		
			
				|  |  | +                                        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                        let pos = self.possible.pos(column, remove);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                        if self.possible.possible[pos].get(values[0] as usize) {
 | 
	
		
			
				|  |  | +                                            self.possible.possible[pos]
 | 
	
		
			
				|  |  | +                                                .set(values[0] as usize, false);
 | 
	
		
			
				|  |  | +                                            found_something = true;
 | 
	
		
			
				|  |  | +                                            pair_removed = true;
 | 
	
		
			
				|  |  | +                                        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                        if self.possible.possible[pos].get(values[1] as usize) {
 | 
	
		
			
				|  |  | +                                            self.possible.possible[pos]
 | 
	
		
			
				|  |  | +                                                .set(values[1] as usize, false);
 | 
	
		
			
				|  |  | +                                            found_something = true;
 | 
	
		
			
				|  |  | +                                            pair_removed = true;
 | 
	
		
			
				|  |  | +                                        }
 | 
	
		
			
				|  |  | +                                    }
 | 
	
		
			
				|  |  | +                                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                if self.possible.xy(gpos).1 == self.possible.xy(fpos).1 {
 | 
	
		
			
				|  |  | +                                    // Matching Y - process row
 | 
	
		
			
				|  |  | +                                    let row = self.possible.xy(gpos).1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                    vpos = 0;
 | 
	
		
			
				|  |  | +                                    for z in self.possible.possible[gpos].iter() {
 | 
	
		
			
				|  |  | +                                        values[vpos] = z + 1;
 | 
	
		
			
				|  |  | +                                        vpos += 1;
 | 
	
		
			
				|  |  | +                                    }
 | 
	
		
			
				|  |  | +                                    for remove in 0..width {
 | 
	
		
			
				|  |  | +                                        if (remove == self.possible.xy(gpos).0)
 | 
	
		
			
				|  |  | +                                            || (remove == self.possible.xy(fpos).0)
 | 
	
		
			
				|  |  | +                                        {
 | 
	
		
			
				|  |  | +                                            continue;
 | 
	
		
			
				|  |  | +                                        }
 | 
	
		
			
				|  |  | +                                        let pos = self.possible.pos(remove, row);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                        if self.possible.possible[pos].get(values[0] as usize) {
 | 
	
		
			
				|  |  | +                                            self.possible.possible[pos]
 | 
	
		
			
				|  |  | +                                                .set(values[0] as usize, false);
 | 
	
		
			
				|  |  | +                                            found_something = true;
 | 
	
		
			
				|  |  | +                                            pair_removed = true;
 | 
	
		
			
				|  |  | +                                        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                        if self.possible.possible[pos].get(values[1] as usize) {
 | 
	
		
			
				|  |  | +                                            self.possible.possible[pos]
 | 
	
		
			
				|  |  | +                                                .set(values[1] as usize, false);
 | 
	
		
			
				|  |  | +                                            found_something = true;
 | 
	
		
			
				|  |  | +                                            pair_removed = true;
 | 
	
		
			
				|  |  | +                                        }
 | 
	
		
			
				|  |  | +                                    }
 | 
	
		
			
				|  |  | +                                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                                /*
 | 
	
		
			
				|  |  | +                                if pair_removed {
 | 
	
		
			
				|  |  | +                                    if debug {
 | 
	
		
			
				|  |  | +                                        println!(
 | 
	
		
			
				|  |  | +                                            "Pair found! {} {}: {} {:?} and {} {:?} !",
 | 
	
		
			
				|  |  | +                                            gidx,
 | 
	
		
			
				|  |  | +                                            fidx,
 | 
	
		
			
				|  |  | +                                            gpos,
 | 
	
		
			
				|  |  | +                                            xy(gpos),
 | 
	
		
			
				|  |  | +                                            fpos,
 | 
	
		
			
				|  |  | +                                            xy(fpos)
 | 
	
		
			
				|  |  | +                                        );
 | 
	
		
			
				|  |  | +                                    }
 | 
	
		
			
				|  |  | +                                }
 | 
	
		
			
				|  |  | +                                */
 | 
	
		
			
				|  |  | +                            }
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          found_something
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -984,6 +1290,15 @@ mod tests {
 | 
	
		
			
				|  |  |          // board.display();
 | 
	
		
			
				|  |  |          let mut solver = AnySolver::new_from(&board);
 | 
	
		
			
				|  |  |          assert!(solver.validate_board());
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        // solver.solve_logic();
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        while (solver.solve_logic()) {
 | 
	
		
			
				|  |  | +            solver.board.display();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        assert!(solver.validate_board());
 | 
	
		
			
				|  |  | +        assert!(solver.board.complete());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          board = AnyBoard::new(4);
 | 
	
		
			
				|  |  |          let result = board.load_from_tld('b', '_', "_bo_j_m_f__dp__ge_h_pcfdo___q__n___qio______df___f__l___hpnm_i___obig_p_qhl__k_m_dq_cn______o_g_p_____bi_kc__jn______fo____gi______eb____jd______jk__ml_bn_____i_m_b______oq_nj_d_n__jck_m_fgbq___i_medp___n__b___dg______qjk___j__p___fgohl_d_qo__mq__g_d_p_le_");
 | 
	
	
		
			
				|  | @@ -1014,6 +1329,15 @@ mod tests {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          let mut solver = AnySolver::new_from(&board);
 | 
	
		
			
				|  |  |          assert!(solver.validate_board());
 | 
	
		
			
				|  |  | +        solver.board.display();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        while (solver.solve_logic()) {
 | 
	
		
			
				|  |  | +            solver.board.display();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        assert!(solver.validate_board());
 | 
	
		
			
				|  |  | +        solver.board.display();
 | 
	
		
			
				|  |  | +        assert!(solver.board.complete());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          let mut board: AnyBoard = AnyBoard::new(5);
 | 
	
		
			
				|  |  |          let result = board.load_from_tld('b', '_', "_m_kzg____h_s_n____ftd_u_u_dh_____f_b_t_w_____yg_c_rl_o_tdhy__m__uvig_w_sk_eg___p_q_jikouys_r_d___mlq_t_sb_emcwg_dlzyo_kp_i_ng__ir_b_fp_vhz_ce_y_jm__w__m__o_k_xul_qbt_d_s__e____otv_dhegn___mfkpz_blr____s_dv_n_mjx_ckg_w_bo_p___kqyelwjcz_____nxumoisdh_z__fp_vbi_______dkx_eg__r_y_mlwf_u__q_i__o_chdv_j_i_he_r_____________p_zl_k_d_vbjh_y__e_p__s_tguc_q_s__qj_kpn_______ufw_hx__i_hvntirfxw_____lbckympjg___u_kz_m_bfn_yvx_h_ir_o____rgm_otlnx___ipfes_kwc____p__c_v_ugh_krj_m_w__x__x__ci_j_qk_mpo_dr_u_zb__ht_i_qe_wjvcy_bhkzx_ng_u_syv___u_c_hsfrlqo_t_e___pj_cn_h_slzr__j__mqgp_y_vd_m_bs_____t_o_n_h_____ez_f_e_ufd____p_g_z____cqr_x_");
 | 
	
	
		
			
				|  | @@ -1328,8 +1652,8 @@ impl<'a> BoardPossible<'a> {
 | 
	
		
			
				|  |  |  */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*
 | 
	
		
			
				|  |  | -  ___  _     _    ____          _      
 | 
	
		
			
				|  |  | - / _ \| | __| |  / ___|___   __| | ___ 
 | 
	
		
			
				|  |  | +  ___  _     _    ____          _
 | 
	
		
			
				|  |  | + / _ \| | __| |  / ___|___   __| | ___
 | 
	
		
			
				|  |  |  | | | | |/ _` | | |   / _ \ / _` |/ _ \
 | 
	
		
			
				|  |  |  | |_| | | (_| | | |__| (_) | (_| |  __/
 | 
	
		
			
				|  |  |   \___/|_|\__,_|  \____\___/ \__,_|\___|
 |