|
@@ -553,7 +553,6 @@ impl AnyPossible {
|
|
(pos, max)
|
|
(pos, max)
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
pub fn find_pairs(&mut self, cellgroup: &[usize]) -> (Vec<(Vec<u8>, Vec<u8>)>, bool) {
|
|
pub fn find_pairs(&mut self, cellgroup: &[usize]) -> (Vec<(Vec<u8>, Vec<u8>)>, bool) {
|
|
// result[value] = indexes where it is located?
|
|
// result[value] = indexes where it is located?
|
|
// Step 1: find values, and their position(s).
|
|
// Step 1: find values, and their position(s).
|
|
@@ -599,20 +598,24 @@ impl AnyPossible {
|
|
}
|
|
}
|
|
|
|
|
|
let count = pos_found.count_set();
|
|
let count = pos_found.count_set();
|
|
|
|
+ /*
|
|
if count == 1 {
|
|
if count == 1 {
|
|
// Single possible item here ... skip this for now.
|
|
// Single possible item here ... skip this for now.
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
+ */
|
|
|
|
|
|
let mut matches = 1;
|
|
let mut matches = 1;
|
|
// Pos contains the numbers in the cell.
|
|
// Pos contains the numbers in the cell.
|
|
let mut pos = Vec::<u8>::new();
|
|
let mut pos = Vec::<u8>::new();
|
|
pos.push(idx);
|
|
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);
|
|
index_pos.push(p);
|
|
if self.possible[cellgroup[p as usize]] != new_possible {
|
|
if self.possible[cellgroup[p as usize]] != new_possible {
|
|
// println!("Update pos {} with {:?}", p, new_possible);
|
|
// println!("Update pos {} with {:?}", p, new_possible);
|
|
- /*
|
|
|
|
|
|
+ /*
|
|
println!(
|
|
println!(
|
|
"Index is {} => {:?}",
|
|
"Index is {} => {:?}",
|
|
cellgroup[p as usize],
|
|
cellgroup[p as usize],
|
|
@@ -648,7 +651,6 @@ impl AnyPossible {
|
|
(pairs, possibles_updated)
|
|
(pairs, possibles_updated)
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/// Display Possible
|
|
/// Display Possible
|
|
/// - Collect all of the possibles, with max length.
|
|
/// - Collect all of the possibles, with max length.
|
|
/// - Display formatted (using 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 struct Pairs {
|
|
pub values: [u8; 2],
|
|
pub values: [u8; 2],
|
|
pub pos: [u8; 2],
|
|
pub pos: [u8; 2],
|
|
}
|
|
}
|
|
|
|
+*/
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
#[derive(Debug, Clone)]
|
|
pub struct AnySolver {
|
|
pub struct AnySolver {
|
|
pub board: AnyBoard,
|
|
pub board: AnyBoard,
|
|
pub possible: AnyPossible,
|
|
pub possible: AnyPossible,
|
|
pub group: AnyGroup,
|
|
pub group: AnyGroup,
|
|
|
|
+ // Is this value set in the given cell?
|
|
pub cell_poss: Vec<GenBits<u32>>,
|
|
pub cell_poss: Vec<GenBits<u32>>,
|
|
}
|
|
}
|
|
|
|
|
|
@@ -813,31 +818,126 @@ impl AnySolver {
|
|
|
|
|
|
// OR, just check row and columns?
|
|
// 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*
|
|
// find_pairs: Finds the pairs (and triples, and quads, and ...) *MOVED to AnyPossible*
|
|
/// Finalize move on the board.
|
|
/// Finalize move on the board.
|
|
/// - This uses the cell index last modified, so we have fewer
|
|
/// - This uses the cell index last modified, so we have fewer
|
|
/// cells to check here. (2 * size) cells.
|
|
/// 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;
|
|
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)));
|
|
// 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)
|
|
// 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
|
|
// 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...");
|
|
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)
|
|
/// - This checks the board for logic fixes. (when column is full/has 1+pair/triple)
|
|
pub fn finalize_move(&mut self) {
|
|
pub fn finalize_move(&mut self) {
|
|
// Process the cells diagonally.
|
|
// 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 {
|
|
for idx in 0..self.board.size {
|
|
self.finalize_cell(idx + idx * self.board.size);
|
|
self.finalize_cell(idx + idx * self.board.size);
|
|
@@ -1611,8 +1717,13 @@ mod tests {
|
|
|
|
|
|
*/
|
|
*/
|
|
solver.possible.display();
|
|
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());
|
|
// assert!(solver.validate_board());
|
|
solver.possible.display();
|
|
solver.possible.display();
|
|
|
|
|
|
@@ -1662,6 +1773,7 @@ mod tests {
|
|
board.set(1, 7, 5);
|
|
board.set(1, 7, 5);
|
|
board.display();
|
|
board.display();
|
|
let mut solver = AnySolver::new_from(&board);
|
|
let mut solver = AnySolver::new_from(&board);
|
|
|
|
+ solver.possible.display();
|
|
|
|
|
|
/*
|
|
/*
|
|
╔═══╦═══╦═══╗
|
|
╔═══╦═══╦═══╗
|
|
@@ -1695,12 +1807,14 @@ mod tests {
|
|
|
|
|
|
println!("RIGHT HERE:");
|
|
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(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);
|
|
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);
|
|
let pairs = solver.possible.find_pairs(g);
|
|
println!("Pairs [ row index 4]: {:?}", pairs);
|
|
println!("Pairs [ row index 4]: {:?}", pairs);
|
|
|
|
|
|
@@ -1750,8 +1864,8 @@ mod tests {
|
|
*/
|
|
*/
|
|
|
|
|
|
println!("RIGHT HERE:");
|
|
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.finalize_cell(3);
|
|
solver.possible.display();
|
|
solver.possible.display();
|
|
|
|
|