|
@@ -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
|
|
|
+ */
|
|
|
}
|
|
|
}
|
|
|
|