|
@@ -588,15 +588,21 @@ pub struct AnySolver {
|
|
pub board: AnyBoard,
|
|
pub board: AnyBoard,
|
|
pub possible: AnyPossible,
|
|
pub possible: AnyPossible,
|
|
pub group: AnyGroup,
|
|
pub group: AnyGroup,
|
|
|
|
+ pub cell_poss: Vec<GenBits<u32>>,
|
|
}
|
|
}
|
|
|
|
|
|
impl AnySolver {
|
|
impl AnySolver {
|
|
/// Construct new solver from given board size. (3,4,5)
|
|
/// Construct new solver from given board size. (3,4,5)
|
|
pub fn new(board_size: u8) -> Self {
|
|
pub fn new(board_size: u8) -> Self {
|
|
|
|
+ let mut default_poss = GenBits::<u32>(0);
|
|
|
|
+ let width: u8 = board_size * board_size;
|
|
|
|
+ default_poss.set_bits(0..width);
|
|
|
|
+
|
|
let mut s = Self {
|
|
let mut s = Self {
|
|
board: AnyBoard::new(board_size),
|
|
board: AnyBoard::new(board_size),
|
|
possible: AnyPossible::new(board_size),
|
|
possible: AnyPossible::new(board_size),
|
|
group: AnyGroup::new(board_size),
|
|
group: AnyGroup::new(board_size),
|
|
|
|
+ cell_poss: vec![default_poss; width as usize * width as usize],
|
|
};
|
|
};
|
|
s.reset_possible();
|
|
s.reset_possible();
|
|
s
|
|
s
|
|
@@ -604,10 +610,17 @@ impl AnySolver {
|
|
|
|
|
|
/// Construct new solver from given board.
|
|
/// Construct new solver from given board.
|
|
pub fn new_from(initial_board: &AnyBoard) -> Self {
|
|
pub fn new_from(initial_board: &AnyBoard) -> Self {
|
|
|
|
+ let mut default_poss = GenBits::<u32>(0);
|
|
|
|
+ default_poss.set_bits(0..initial_board.width);
|
|
|
|
+
|
|
let mut s = AnySolver {
|
|
let mut s = AnySolver {
|
|
board: initial_board.clone(),
|
|
board: initial_board.clone(),
|
|
possible: AnyPossible::new(initial_board.size),
|
|
possible: AnyPossible::new(initial_board.size),
|
|
group: AnyGroup::new(initial_board.size),
|
|
group: AnyGroup::new(initial_board.size),
|
|
|
|
+ cell_poss: vec![
|
|
|
|
+ default_poss;
|
|
|
|
+ initial_board.width as usize * initial_board.width as usize
|
|
|
|
+ ],
|
|
};
|
|
};
|
|
s.reset_possible();
|
|
s.reset_possible();
|
|
s
|
|
s
|
|
@@ -625,6 +638,8 @@ impl AnySolver {
|
|
/// Process a move
|
|
/// Process a move
|
|
/// - Remove value from rows, columns, and cells.
|
|
/// - Remove value from rows, columns, and cells.
|
|
/// - Clear possibles from (x,y) position, it's filled.
|
|
/// - Clear possibles from (x,y) position, it's filled.
|
|
|
|
+ /// - **THIS PANICS** debug_assert!, panics in test validated_board
|
|
|
|
+ /// TO FIX: This needs to return an error. (someway, somehow)
|
|
pub fn process_move(&mut self, x: u8, y: u8, value: u8) {
|
|
pub fn process_move(&mut self, x: u8, y: u8, value: u8) {
|
|
debug_assert!(
|
|
debug_assert!(
|
|
x <= self.board.width && y <= self.board.width,
|
|
x <= self.board.width && y <= self.board.width,
|
|
@@ -654,8 +669,84 @@ impl AnySolver {
|
|
self.possible.set(*g, val, false);
|
|
self.possible.set(*g, val, false);
|
|
}
|
|
}
|
|
let idx = self.possible.pos(x, y);
|
|
let idx = self.possible.pos(x, y);
|
|
- self.possible.possible[idx] = GenBits::<u32>(0); // .clear();
|
|
|
|
|
|
+ self.possible.possible[idx] = GenBits::<u32>(0);
|
|
self.board.board[idx] = value;
|
|
self.board.board[idx] = value;
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+ // When working with GenBits, remember to use value -1
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ let ok = self.cell_poss[cell_index as usize].get(value as usize-1);
|
|
|
|
+ if !ok {
|
|
|
|
+ println!("{:?}", self.cell_poss);
|
|
|
|
+ println!("Cell {} ({},{})={}", cell_index, x, y, value);
|
|
|
|
+ }
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ // Tests are run as debug, and this kills things...
|
|
|
|
+ // Like the invalid board in validated_board test.
|
|
|
|
+ let cell_index = self.group.which_cell(x, y);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ Never use this code. It asserts/panics on invalid boards.
|
|
|
|
+ (Which is what validate_board checks...)
|
|
|
|
+
|
|
|
|
+ debug_assert!(
|
|
|
|
+ self.cell_poss[cell_index as usize].get(value as usize - 1),
|
|
|
|
+ "Cell {} ({},{})={}",
|
|
|
|
+ cell_index,
|
|
|
|
+ x,
|
|
|
|
+ y,
|
|
|
|
+ value
|
|
|
|
+ );
|
|
|
|
+ */
|
|
|
|
+ self.cell_poss[cell_index as usize].set(value as usize - 1, false);
|
|
|
|
+
|
|
|
|
+ self.finalize_cell(cell_index);
|
|
|
|
+
|
|
|
|
+ // Should I do the checks here for the logic possible fix?
|
|
|
|
+ // Or, should I make it a different function?
|
|
|
|
+ // Put somewhere else, since it has to re-check the entire board!
|
|
|
|
+
|
|
|
|
+ // OR, just check row and columns?
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// Finalize move on the board.
|
|
|
|
+ /// - This uses the cell index last modified, so we have fewer
|
|
|
|
+ /// cells to check here. (2 * size) cells.
|
|
|
|
+ pub fn finalize_cell(&mut self, index:u8) {
|
|
|
|
+ let size = self.board.size;
|
|
|
|
+
|
|
|
|
+ // Check columns
|
|
|
|
+ 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);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 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);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// Finalize move(s) on the board.
|
|
|
|
+ /// - This checks the board for logic fixes. (when column is full/has 1+pair/triple)
|
|
|
|
+ pub fn finalize_move(&mut self) {
|
|
|
|
+ for idx in 0..3 {
|
|
|
|
+ let mut _ix: u8 = idx * 3;
|
|
|
|
+ let mut _iy: u8 = idx * 3;
|
|
|
|
+
|
|
|
|
+ println!("Index {} x {} y {}", idx, _ix, _iy);
|
|
|
|
+ // Check cell rows
|
|
|
|
+
|
|
|
|
+ // Check cell columns
|
|
|
|
+ }
|
|
|
|
+ assert!(false, "Boing!");
|
|
}
|
|
}
|
|
|
|
|
|
/// Validate the board
|
|
/// Validate the board
|
|
@@ -666,6 +757,14 @@ impl AnySolver {
|
|
let mut has_blanks = false;
|
|
let mut has_blanks = false;
|
|
|
|
|
|
self.possible.clear();
|
|
self.possible.clear();
|
|
|
|
+ // reset cell possible
|
|
|
|
+ let mut default_poss = GenBits::<u32>(0);
|
|
|
|
+ default_poss.set_bits(0..self.board.width);
|
|
|
|
+
|
|
|
|
+ for x in 0..self.board.width {
|
|
|
|
+ self.cell_poss[x as usize] = default_poss;
|
|
|
|
+ }
|
|
|
|
+
|
|
for y in 0..self.board.width {
|
|
for y in 0..self.board.width {
|
|
for x in 0..self.board.width {
|
|
for x in 0..self.board.width {
|
|
let value = self.board.get(x, y);
|
|
let value = self.board.get(x, y);
|
|
@@ -714,6 +813,15 @@ impl AnySolver {
|
|
/// - When something has changed, and the possibles are out of sync.
|
|
/// - When something has changed, and the possibles are out of sync.
|
|
pub fn reset_possible(&mut self) {
|
|
pub fn reset_possible(&mut self) {
|
|
self.possible.clear();
|
|
self.possible.clear();
|
|
|
|
+
|
|
|
|
+ // reset cell possible
|
|
|
|
+ let mut default_poss = GenBits::<u32>(0);
|
|
|
|
+ default_poss.set_bits(0..self.board.width);
|
|
|
|
+
|
|
|
|
+ for x in 0..self.board.width {
|
|
|
|
+ self.cell_poss[x as usize] = default_poss;
|
|
|
|
+ }
|
|
|
|
+
|
|
for y in 0..self.board.width {
|
|
for y in 0..self.board.width {
|
|
for x in 0..self.board.width {
|
|
for x in 0..self.board.width {
|
|
let value = self.board.get(x, y);
|
|
let value = self.board.get(x, y);
|
|
@@ -807,6 +915,11 @@ impl AnySolver {
|
|
// Failure
|
|
// Failure
|
|
self.board.copy(&backup.board);
|
|
self.board.copy(&backup.board);
|
|
self.possible.copy(&backup.possible);
|
|
self.possible.copy(&backup.possible);
|
|
|
|
+
|
|
|
|
+ for i in 0..backup.cell_poss.len() {
|
|
|
|
+ self.cell_poss[i] = backup.cell_poss[i];
|
|
|
|
+ }
|
|
|
|
+ // self.cell_poss.copy( backup.cell_poss);
|
|
}
|
|
}
|
|
|
|
|
|
// We've run out of possible.
|
|
// We've run out of possible.
|
|
@@ -1351,6 +1464,120 @@ impl AnySolver {
|
|
mod tests {
|
|
mod tests {
|
|
use crate::sudoku::*;
|
|
use crate::sudoku::*;
|
|
|
|
|
|
|
|
+ #[ignore]
|
|
|
|
+ #[test]
|
|
|
|
+ fn logic_test() {
|
|
|
|
+ let mut board = AnyBoard::new(3);
|
|
|
|
+ board.set(1, 0, 2);
|
|
|
|
+ board.set(0, 3, 3);
|
|
|
|
+ board.set(0, 4, 4);
|
|
|
|
+ board.set(0, 5, 5);
|
|
|
|
+ board.display();
|
|
|
|
+ let mut solver = AnySolver::new_from(&board);
|
|
|
|
+ /*
|
|
|
|
+ ╔═══╦═══╦═══╗
|
|
|
|
+ ║ 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
|
|
|
|
+ ^ This shows the logic bug.
|
|
|
|
+ (3,7), (3,8) and (3,9) should not contain 2!
|
|
|
|
+
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ assert!(solver.validate_board());
|
|
|
|
+ solver.possible.display();
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ // Validate the broken possible board.
|
|
|
|
+ for i in 3..9 {
|
|
|
|
+ assert!(!solver.possible.get(solver.possible.pos(1, i), 2), "Possible ({},{}) does not have 2", 1+1, i+1);
|
|
|
|
+ assert!(solver.possible.get(solver.possible.pos(2, i), 2), "Possible ({},{}) does have 2", 2+1, i+1);
|
|
|
|
+ if i > 6 {
|
|
|
|
+ assert!(solver.possible.get(solver.possible.pos(0, i), 2), "Possible ({},{}) does have 2", 0+1, i+1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ */
|
|
|
|
+ for i in 6..9 {
|
|
|
|
+ assert!(
|
|
|
|
+ !solver.possible.get(solver.possible.pos(2, i), 2),
|
|
|
|
+ "Possible ({},{}) can not contain 2.",
|
|
|
|
+ 2 + 1,
|
|
|
|
+ i + 1
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Test 2 - pairs
|
|
|
|
+
|
|
|
|
+ // let p = solver.possible.get(solver.possible.pos(2,4), 2);
|
|
|
|
+
|
|
|
|
+ println!("--- logic_test ---");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[ignore]
|
|
|
|
+ #[test]
|
|
|
|
+ fn logic_test_pairs() {
|
|
|
|
+ let mut board = AnyBoard::new(3);
|
|
|
|
+ board.set(1, 0, 2);
|
|
|
|
+ board.set(2, 1, 3);
|
|
|
|
+ board.set(2,2, 5);
|
|
|
|
+ board.set(1, 6, 3);
|
|
|
|
+ board.set(0, 4, 4);
|
|
|
|
+ board.set(1, 7, 5);
|
|
|
|
+ board.display();
|
|
|
|
+ let mut solver = AnySolver::new_from(&board);
|
|
|
|
+ /*
|
|
|
|
+ ╔═══╦═══╦═══╗
|
|
|
|
+ ║ 2 ║ ║ ║
|
|
|
|
+ ║ 3║ ║ ║
|
|
|
|
+ ║ 5║ ║ ║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║P ║ ║ ║
|
|
|
|
+ ║4 ║ ║ ║
|
|
|
|
+ ║P ║ ║ ║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║ 3 ║ ║ ║
|
|
|
|
+ ║ 5 ║ ║ ║
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ╚═══╩═══╩═══╝
|
|
|
|
+ P = Possible pair (3,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
|
|
|
|
+ ^ This shows the logic bug.
|
|
|
|
+ (3,7), (3,8) and (3,9) should not contain 2!
|
|
|
|
+
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ assert!(solver.validate_board());
|
|
|
|
+ solver.possible.display();
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
#[test]
|
|
#[test]
|
|
fn display_board() {
|
|
fn display_board() {
|
|
let mut board = AnyBoard::new(3);
|
|
let mut board = AnyBoard::new(3);
|
|
@@ -1382,13 +1609,44 @@ mod tests {
|
|
|
|
|
|
solver.reset_possible();
|
|
solver.reset_possible();
|
|
|
|
|
|
- if solver.solve_logic() {
|
|
|
|
|
|
+ if !solver.solve_logic() {
|
|
solver.board.display();
|
|
solver.board.display();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ ╔═══╦═══╦═══╗
|
|
|
|
+ ║541║768║329║
|
|
|
|
+ ║973║512║684║
|
|
|
|
+ ║286║934║751║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║869║157║243║
|
|
|
|
+ ║325║486║197║
|
|
|
|
+ ║714║293║865║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║658║341║972║
|
|
|
|
+ ║197║625║438║
|
|
|
|
+ ║432║879║516║
|
|
|
|
+ ╚═══╩═══╩═══╝
|
|
|
|
+ */
|
|
assert!(solver.validate_board());
|
|
assert!(solver.validate_board());
|
|
assert!(solver.board.complete());
|
|
assert!(solver.board.complete());
|
|
|
|
|
|
|
|
+ let strings = solver.board.to_strings();
|
|
|
|
+ assert_eq!(
|
|
|
|
+ strings,
|
|
|
|
+ vec![
|
|
|
|
+ "541768329",
|
|
|
|
+ "973512684",
|
|
|
|
+ "286934751",
|
|
|
|
+ "869157243",
|
|
|
|
+ "325486197",
|
|
|
|
+ "714293865",
|
|
|
|
+ "658341972",
|
|
|
|
+ "197625438",
|
|
|
|
+ "432879516"
|
|
|
|
+ ]
|
|
|
|
+ );
|
|
|
|
+
|
|
board = AnyBoard::new(4);
|
|
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_");
|
|
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_");
|
|
assert!(result.is_ok());
|
|
assert!(result.is_ok());
|
|
@@ -1418,15 +1676,58 @@ mod tests {
|
|
|
|
|
|
let mut solver = AnySolver::new_from(&board);
|
|
let mut solver = AnySolver::new_from(&board);
|
|
assert!(solver.validate_board());
|
|
assert!(solver.validate_board());
|
|
- solver.board.display();
|
|
|
|
|
|
|
|
- if solver.solve_logic() {
|
|
|
|
|
|
+ if !solver.solve_logic() {
|
|
solver.board.display();
|
|
solver.board.display();
|
|
}
|
|
}
|
|
-
|
|
|
|
- assert!(solver.validate_board());
|
|
|
|
|
|
+ /*
|
|
solver.board.display();
|
|
solver.board.display();
|
|
|
|
+ ╔════╦════╦════╦════╗
|
|
|
|
+ ║HDLJ║MKOB║FPEC║GAIN║
|
|
|
|
+ ║AKOE║NCFD║GILH║PMBJ║
|
|
|
|
+ ║NGFB║APLI║OJKM║HCDE║
|
|
|
|
+ ║MIPC║HJEG║DBAN║KFOL║
|
|
|
|
+ ╠════╬════╬════╬════╣
|
|
|
|
+ ║IOHK║FBDJ║AECG║LNMP║
|
|
|
|
+ ║JBNF║CMPE║HLOI║DKAG║
|
|
|
|
+ ║LEMD║OGAN║PKFB║CHJI║
|
|
|
|
+ ║GCAP║ILHK║MNDJ║OBEF║
|
|
|
|
+ ╠════╬════╬════╬════╣
|
|
|
|
+ ║ENIG║POCM║KABD║JLFH║
|
|
|
|
+ ║PFKO║GEJA║IMHL║BDNC║
|
|
|
|
+ ║DHJM║KIBL║CFNO║EPGA║
|
|
|
|
+ ║CABL║DHNF║JGPE║MIKO║
|
|
|
|
+ ╠════╬════╬════╬════╣
|
|
|
|
+ ║OPCA║ENKH║BDGF║IJLM║
|
|
|
|
+ ║BLEH║JDIP║NOMA║FGCK║
|
|
|
|
+ ║KJGN║BFMO║LCIP║AEHD║
|
|
|
|
+ ║FMDI║LAGC║EHJK║NOPB║
|
|
|
|
+ ╚════╩════╩════╩════╝
|
|
|
|
+ */
|
|
|
|
+ assert!(solver.validate_board());
|
|
assert!(solver.board.complete());
|
|
assert!(solver.board.complete());
|
|
|
|
+ let strings: Vec<String> = solver.board.to_strings();
|
|
|
|
+ assert_eq!(
|
|
|
|
+ strings,
|
|
|
|
+ vec![
|
|
|
|
+ "HDLJMKOBFPECGAIN",
|
|
|
|
+ "AKOENCFDGILHPMBJ",
|
|
|
|
+ "NGFBAPLIOJKMHCDE",
|
|
|
|
+ "MIPCHJEGDBANKFOL",
|
|
|
|
+ "IOHKFBDJAECGLNMP",
|
|
|
|
+ "JBNFCMPEHLOIDKAG",
|
|
|
|
+ "LEMDOGANPKFBCHJI",
|
|
|
|
+ "GCAPILHKMNDJOBEF",
|
|
|
|
+ "ENIGPOCMKABDJLFH",
|
|
|
|
+ "PFKOGEJAIMHLBDNC",
|
|
|
|
+ "DHJMKIBLCFNOEPGA",
|
|
|
|
+ "CABLDHNFJGPEMIKO",
|
|
|
|
+ "OPCAENKHBDGFIJLM",
|
|
|
|
+ "BLEHJDIPNOMAFGCK",
|
|
|
|
+ "KJGNBFMOLCIPAEHD",
|
|
|
|
+ "FMDILAGCEHJKNOPB"
|
|
|
|
+ ]
|
|
|
|
+ );
|
|
|
|
|
|
let mut board: AnyBoard = AnyBoard::new(5);
|
|
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_");
|
|
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_");
|
|
@@ -1465,6 +1766,79 @@ mod tests {
|
|
);
|
|
);
|
|
let mut solver = AnySolver::new_from(&board);
|
|
let mut solver = AnySolver::new_from(&board);
|
|
assert!(solver.validate_board());
|
|
assert!(solver.validate_board());
|
|
|
|
+
|
|
|
|
+ // This takes awhile to solve...
|
|
|
|
+ if !solver.solve_logic() {
|
|
|
|
+ solver.board.display();
|
|
|
|
+ }
|
|
|
|
+ assert!(solver.validate_board());
|
|
|
|
+ assert!(solver.board.complete());
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ solver.board.display();
|
|
|
|
+ ╔═════╦═════╦═════╦═════╦═════╗
|
|
|
|
+ ║UTODP║FIBGA║YMHQR║NKCEW║SXJLV║
|
|
|
|
+ ║LHQFI║MYTEJ║SXWCN║GVPAR║OUBKD║
|
|
|
|
+ ║XCKES║WLNRP║VFGJB║UTQOD║HYMAI║
|
|
|
|
+ ║JGAVW║HOSKX║ELDUP║MIFYB║QCNRT║
|
|
|
|
+ ║YMNBR║QVUCD║OKTAI║SJLXH║PWGFE║
|
|
|
|
+ ╠═════╬═════╬═════╬═════╬═════╣
|
|
|
|
+ ║FJMOA║RNPUK║LVQIS║HYGBX║DTEWC║
|
|
|
|
+ ║KWSYT║AHCXV║UEBGJ║QONDI║LFRPM║
|
|
|
|
+ ║QRCPD║TJGMI║AYNWO║ELSUF║VBKHX║
|
|
|
|
+ ║VNGUL║EQDSB║HTFXM║WCKRP║IAYOJ║
|
|
|
|
+ ║HEXIB║OWFLY║RDPKC║VAMTJ║UGQSN║
|
|
|
|
+ ╠═════╬═════╬═════╬═════╬═════╣
|
|
|
|
+ ║GQPHV║CTMIS║XJANL║YEWFK║BRDUO║
|
|
|
|
+ ║OABJF║UKVWQ║IPCDY║RMTGL║XESNH║
|
|
|
|
+ ║RYLNU║GXHDE║TWVMK║PBASO║CQIJF║
|
|
|
|
+ ║WSETC║YPRBF║GHUOQ║DXIJN║AKVML║
|
|
|
|
+ ║MIDXK║NALJO║BRSEF║CUHQV║GPWTY║
|
|
|
|
+ ╠═════╬═════╬═════╬═════╬═════╣
|
|
|
|
+ ║AVTRY║BSEFM║PQXHD║KWOIC║JNLGU║
|
|
|
|
+ ║BOUSX║DGJHW║CNLRT║AFEMQ║YVPIK║
|
|
|
|
+ ║IPHQN║KCOVT║JAMYE║BGDLU║WSFXR║
|
|
|
|
+ ║DKFMG║XUYQL║WBISV║JPRNT║EHOCA║
|
|
|
|
+ ║ELWCJ║PRIAN║KGOFU║XHYVS║MDTQB║
|
|
|
|
+ ╠═════╬═════╬═════╬═════╬═════╣
|
|
|
|
+ ║SUVWO║IEANH║DCRTG║LQJKY║FMXBP║
|
|
|
|
+ ║CXIGE║LMKTR║FUYBW║OSVPA║NJHDQ║
|
|
|
|
+ ║PFRAH║JDQOC║MSKVX║INBWE║TLUYG║
|
|
|
|
+ ║TDJLQ║SBXYG║NIEPA║FRUHM║KOCVW║
|
|
|
|
+ ║NBYKM║VFWPU║QOJLH║TDXCG║RIAES║
|
|
|
|
+ ╚═════╩═════╩═════╩═════╩═════╝
|
|
|
|
+ */
|
|
|
|
+ let strings: Vec<String> = solver.board.to_strings();
|
|
|
|
+ assert_eq!(
|
|
|
|
+ strings,
|
|
|
|
+ vec![
|
|
|
|
+ "UTODPFIBGAYMHQRNKCEWSXJLV",
|
|
|
|
+ "LHQFIMYTEJSXWCNGVPAROUBKD",
|
|
|
|
+ "XCKESWLNRPVFGJBUTQODHYMAI",
|
|
|
|
+ "JGAVWHOSKXELDUPMIFYBQCNRT",
|
|
|
|
+ "YMNBRQVUCDOKTAISJLXHPWGFE",
|
|
|
|
+ "FJMOARNPUKLVQISHYGBXDTEWC",
|
|
|
|
+ "KWSYTAHCXVUEBGJQONDILFRPM",
|
|
|
|
+ "QRCPDTJGMIAYNWOELSUFVBKHX",
|
|
|
|
+ "VNGULEQDSBHTFXMWCKRPIAYOJ",
|
|
|
|
+ "HEXIBOWFLYRDPKCVAMTJUGQSN",
|
|
|
|
+ "GQPHVCTMISXJANLYEWFKBRDUO",
|
|
|
|
+ "OABJFUKVWQIPCDYRMTGLXESNH",
|
|
|
|
+ "RYLNUGXHDETWVMKPBASOCQIJF",
|
|
|
|
+ "WSETCYPRBFGHUOQDXIJNAKVML",
|
|
|
|
+ "MIDXKNALJOBRSEFCUHQVGPWTY",
|
|
|
|
+ "AVTRYBSEFMPQXHDKWOICJNLGU",
|
|
|
|
+ "BOUSXDGJHWCNLRTAFEMQYVPIK",
|
|
|
|
+ "IPHQNKCOVTJAMYEBGDLUWSFXR",
|
|
|
|
+ "DKFMGXUYQLWBISVJPRNTEHOCA",
|
|
|
|
+ "ELWCJPRIANKGOFUXHYVSMDTQB",
|
|
|
|
+ "SUVWOIEANHDCRTGLQJKYFMXBP",
|
|
|
|
+ "CXIGELMKTRFUYBWOSVPANJHDQ",
|
|
|
|
+ "PFRAHJDQOCMSKVXINBWETLUYG",
|
|
|
|
+ "TDJLQSBXYGNIEPAFRUHMKOCVW",
|
|
|
|
+ "NBYKMVFWPUQOJLHTDXCGRIAES"
|
|
|
|
+ ]
|
|
|
|
+ );
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -1557,7 +1931,23 @@ mod tests {
|
|
board.set(0, 8, 7);
|
|
board.set(0, 8, 7);
|
|
board.set(1, 8, 8);
|
|
board.set(1, 8, 8);
|
|
board.set(2, 8, 9);
|
|
board.set(2, 8, 9);
|
|
|
|
+ /*
|
|
// board.display();
|
|
// board.display();
|
|
|
|
+ ╔═══╦═══╦═══╗
|
|
|
|
+ ║ ║ 1 ║ ║
|
|
|
|
+ ║ ║ 2 ║ ║
|
|
|
|
+ ║ ║ 3 ║ ║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║ ║ 4 ║ ║
|
|
|
|
+ ║ ║ 5 ║ ║
|
|
|
|
+ ║ ║ 6 ║ ║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ║789║ ! ║ ║
|
|
|
|
+ ╚═══╩═══╩═══╝
|
|
|
|
+ The ! can't possibly be anything.
|
|
|
|
+ */
|
|
|
|
|
|
let mut solver = AnySolver::new_from(&board);
|
|
let mut solver = AnySolver::new_from(&board);
|
|
assert!(!solver.validate_board());
|
|
assert!(!solver.validate_board());
|
|
@@ -1566,9 +1956,28 @@ mod tests {
|
|
let mut board = AnyBoard::new(3);
|
|
let mut board = AnyBoard::new(3);
|
|
board.set(4, 0, 1);
|
|
board.set(4, 0, 1);
|
|
board.set(4, 1, 1);
|
|
board.set(4, 1, 1);
|
|
|
|
+ /*
|
|
// board.display();
|
|
// board.display();
|
|
|
|
+ ╔═══╦═══╦═══╗
|
|
|
|
+ ║ ║ 1 ║ ║
|
|
|
|
+ ║ ║ 1 ║ ║
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ║ ║ ║ ║
|
|
|
|
+ ╚═══╩═══╩═══╝
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ // Because of the new AnySolver.process_move code --
|
|
|
|
+ // This panics (as would validate_board!)
|
|
|
|
|
|
let mut solver = AnySolver::new_from(&board);
|
|
let mut solver = AnySolver::new_from(&board);
|
|
|
|
+
|
|
assert!(!solver.validate_board());
|
|
assert!(!solver.validate_board());
|
|
|
|
|
|
// Invalid board: Has two 1's in same row & cell.
|
|
// Invalid board: Has two 1's in same row & cell.
|