|
@@ -453,6 +453,39 @@ impl AnyBoard {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// Ok! This is interesting:
|
|
|
+
|
|
|
+use std::ops::{Index, IndexMut};
|
|
|
+
|
|
|
+impl Index<usize> for AnyBoard {
|
|
|
+ type Output = u8;
|
|
|
+
|
|
|
+ fn index<'a>(&'a self, i:usize) -> &'a u8 {
|
|
|
+ &self.board[i]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Index<(u8,u8)> for AnyBoard {
|
|
|
+ type Output = u8;
|
|
|
+
|
|
|
+ fn index<'a>(&'a self, i: (u8,u8)) -> &'a u8 {
|
|
|
+ &self.board[self.pos(i.0, i.1)]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl IndexMut<usize> for AnyBoard {
|
|
|
+ fn index_mut<'a>(&'a mut self, i:usize) -> &'a mut u8 {
|
|
|
+ &mut self.board[i]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl IndexMut<(u8,u8)> for AnyBoard {
|
|
|
+ fn index_mut<'a>(&'a mut self, i: (u8,u8)) -> &'a mut u8 {
|
|
|
+ let idx = self.pos(i.0, i.1);
|
|
|
+ &mut self.board[idx]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// Need to use u32, so 5*5=25, 25 bits can be accessed.
|
|
|
// u16 is fine for 3*3=9.
|
|
|
|
|
@@ -711,6 +744,35 @@ impl AnyPossible {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl Index<usize> for AnyPossible {
|
|
|
+ type Output = GenBits;
|
|
|
+
|
|
|
+ fn index<'a>(&'a self, i:usize) -> &'a GenBits {
|
|
|
+ &self.possible[i]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Index<(u8,u8)> for AnyPossible {
|
|
|
+ type Output = GenBits;
|
|
|
+
|
|
|
+ fn index<'a>(&'a self, i: (u8,u8)) -> &'a GenBits {
|
|
|
+ &self.possible[self.pos(i.0, i.1)]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl IndexMut<usize> for AnyPossible {
|
|
|
+ fn index_mut<'a>(&'a mut self, i:usize) -> &'a mut GenBits {
|
|
|
+ &mut self.possible[i]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl IndexMut<(u8,u8)> for AnyPossible {
|
|
|
+ fn index_mut<'a>(&'a mut self, i: (u8,u8)) -> &'a mut GenBits {
|
|
|
+ let idx = self.pos(i.0, i.1);
|
|
|
+ &mut self.possible[idx]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
An idea I have for AnySolver is to store the AnyPossible as
|
|
|
sections. row/column/cell.
|
|
@@ -870,7 +932,8 @@ impl AnySolver {
|
|
|
// I might want to save the pair information.
|
|
|
|
|
|
for cell in 0..width {
|
|
|
- let _ = self.possible
|
|
|
+ let _ = self
|
|
|
+ .possible
|
|
|
.find_pairs(self.group.group(Groups::Cell, cell));
|
|
|
}
|
|
|
|
|
@@ -892,9 +955,9 @@ impl AnySolver {
|
|
|
let width = self.board.width;
|
|
|
let size = self.board.size;
|
|
|
// let mut update: bool = false;
|
|
|
-
|
|
|
+ const NOISY: bool = false;
|
|
|
// use width, not size. ;)
|
|
|
- let mut cell_has_value = GenBits::new(self.board.max_index);
|
|
|
+ let mut cell_has_value = GenBits::new(self.board.max_index);
|
|
|
// vec![false; self.board.max_index];
|
|
|
|
|
|
let mut cell_update = vec![false; width as usize];
|
|
@@ -918,7 +981,9 @@ impl AnySolver {
|
|
|
cell_has_value.set(p, true); // [p as usize] = true;
|
|
|
}
|
|
|
|
|
|
- println!("Value {} : Pos {}", value, cell_has_value);
|
|
|
+ if NOISY {
|
|
|
+ println!("Value {} : Pos {}", value, cell_has_value);
|
|
|
+ }
|
|
|
|
|
|
// cell_has_value gives me the indexes that contain value.
|
|
|
// I need to process cell rows/columns...
|
|
@@ -1029,9 +1094,11 @@ impl AnySolver {
|
|
|
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}"
|
|
|
- );
|
|
|
+ if NOISY {
|
|
|
+ println!(
|
|
|
+ "finalize_cell({cell_index}): ({cell_x},{cell_y}) top {top_cell} left {left_cell}"
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
// Ranges are consumed.
|
|
|
|
|
@@ -1080,7 +1147,9 @@ impl AnySolver {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- println!("finalize_cell ends...");
|
|
|
+ if NOISY {
|
|
|
+ println!("finalize_cell ends...");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// Finalize move(s) on the board.
|
|
@@ -1099,6 +1168,7 @@ impl AnySolver {
|
|
|
self.finalize_cell(idx + idx * self.board.size);
|
|
|
}
|
|
|
*/
|
|
|
+ println!("TODO");
|
|
|
}
|
|
|
|
|
|
/// Validate the board
|
|
@@ -1821,7 +1891,19 @@ impl AnySolver {
|
|
|
mod tests {
|
|
|
use crate::sudoku::*;
|
|
|
|
|
|
- #[ignore]
|
|
|
+ #[test]
|
|
|
+ fn board_index_test() {
|
|
|
+ let mut board = AnyBoard::new(3);
|
|
|
+ board[(1,0)] = 2;
|
|
|
+ board[(0,3)] = 3;
|
|
|
+ board[(0,4)] = 4;
|
|
|
+ board[(0,5)] = 5;
|
|
|
+ board[3 + 6 * 3] = 8;
|
|
|
+ board.display();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ #[ignore = "Finalize not completed (NNY!)"]
|
|
|
#[test]
|
|
|
fn logic_test() {
|
|
|
let mut board = AnyBoard::new(3);
|
|
@@ -1830,7 +1912,7 @@ mod tests {
|
|
|
board.set(0, 4, 4);
|
|
|
board.set(0, 5, 5);
|
|
|
board.display();
|
|
|
-
|
|
|
+
|
|
|
let solver = AnySolver::new_from(&board);
|
|
|
/*
|
|
|
╔═══╦═══╦═══╗
|
|
@@ -1968,7 +2050,7 @@ mod tests {
|
|
|
// Running just this test:
|
|
|
// cargo test -p sudoku logic_test_pairs -- --ignored --show-output
|
|
|
|
|
|
- #[ignore]
|
|
|
+ #[ignore = "Finalized not completed (NNY!)"]
|
|
|
#[test]
|
|
|
fn logic_test_pairs() {
|
|
|
let mut board = AnyBoard::new(3);
|
|
@@ -1980,21 +2062,21 @@ mod tests {
|
|
|
board.set(1, 7, 5);
|
|
|
board.display();
|
|
|
/*
|
|
|
- ╔═══╦═══╦═══╗
|
|
|
- ║ 2 ║ ║ ║
|
|
|
- ║ 3║ ║ ║
|
|
|
- ║ 5║ ║ ║
|
|
|
- ╠═══╬═══╬═══╣
|
|
|
- ║P ║ ║ ║
|
|
|
- ║4 ║ ║ ║
|
|
|
- ║P ║ ║ ║
|
|
|
- ╠═══╬═══╬═══╣
|
|
|
- ║ 3 ║ ║ ║
|
|
|
- ║ 5 ║ ║ ║
|
|
|
- ║ ║ ║ ║
|
|
|
- ╚═══╩═══╩═══╝
|
|
|
- P = Possible pair (3,5)
|
|
|
- */
|
|
|
+ ╔═══╦═══╦═══╗
|
|
|
+ ║ 2 ║ ║ ║
|
|
|
+ ║ 3║ ║ ║
|
|
|
+ ║ 5║ ║ ║
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
+ ║P ║ ║ ║
|
|
|
+ ║4 ║ ║ ║
|
|
|
+ ║P ║ ║ ║
|
|
|
+ ╠═══╬═══╬═══╣
|
|
|
+ ║ 3 ║ ║ ║
|
|
|
+ ║ 5 ║ ║ ║
|
|
|
+ ║ ║ ║ ║
|
|
|
+ ╚═══╩═══╩═══╝
|
|
|
+ P = Possible pair (3,5)
|
|
|
+ */
|
|
|
let mut solver = AnySolver::new_from(&board);
|
|
|
|
|
|
solver.possible.display();
|
|
@@ -2025,18 +2107,18 @@ mod tests {
|
|
|
// solver.finalize_cell(3);
|
|
|
solver.possible.display();
|
|
|
/*
|
|
|
- (1,1):1,6,7,8,9 (2,1): (3,1):1,4,6,7,8,9 (4,1):1,3,4,5,6,7,8,9 (5,1):1,3,4,5,6,7,8,9 (6,1):1,3,4,5,6,7,8,9 (7,1):1,3,4,5,6,7,8,9 (8,1):1,3,4,5,6,7,8,9 (9,1):1,3,4,5,6,7,8,9
|
|
|
- (1,2):1,6,7,8,9 (2,2):1,4,6,7,8,9 (3,2): (4,2):1,2,4,5,6,7,8,9 (5,2):1,2,4,5,6,7,8,9 (6,2):1,2,4,5,6,7,8,9 (7,2):1,2,4,5,6,7,8,9 (8,2):1,2,4,5,6,7,8,9 (9,2):1,2,4,5,6,7,8,9
|
|
|
- (1,3):1,6,7,8,9 (2,3):1,4,6,7,8,9 (3,3): (4,3):1,2,3,4,6,7,8,9 (5,3):1,2,3,4,6,7,8,9 (6,3):1,2,3,4,6,7,8,9 (7,3):1,2,3,4,6,7,8,9 (8,3):1,2,3,4,6,7,8,9 (9,3):1,2,3,4,6,7,8,9
|
|
|
- (1,4):3,5 (2,4):1,6,7,8,9 (3,4):1,2,6,7,8,9 (4,4):1,2,3,4,5,6,7,8,9 (5,4):1,2,3,4,5,6,7,8,9 (6,4):1,2,3,4,5,6,7,8,9 (7,4):1,2,3,4,5,6,7,8,9 (8,4):1,2,3,4,5,6,7,8,9 (9,4):1,2,3,4,5,6,7,8,9
|
|
|
- (1,5): (2,5):1,6,7,8,9 (3,5):1,2,6,7,8,9 (4,5):1,2,3,5,6,7,8,9 (5,5):1,2,3,5,6,7,8,9 (6,5):1,2,3,5,6,7,8,9 (7,5):1,2,3,5,6,7,8,9 (8,5):1,2,3,5,6,7,8,9 (9,5):1,2,3,5,6,7,8,9
|
|
|
- (1,6):3,5 (2,6):1,6,7,8,9 (3,6):1,2,6,7,8,9 (4,6):1,2,3,4,5,6,7,8,9 (5,6):1,2,3,4,5,6,7,8,9 (6,6):1,2,3,4,5,6,7,8,9 (7,6):1,2,3,4,5,6,7,8,9 (8,6):1,2,3,4,5,6,7,8,9 (9,6):1,2,3,4,5,6,7,8,9
|
|
|
- (1,7):1,2,6,7,8,9 (2,7): (3,7):1,2,4,6,7,8,9 (4,7):1,2,4,5,6,7,8,9 (5,7):1,2,4,5,6,7,8,9 (6,7):1,2,4,5,6,7,8,9 (7,7):1,2,4,5,6,7,8,9 (8,7):1,2,4,5,6,7,8,9 (9,7):1,2,4,5,6,7,8,9
|
|
|
- (1,8):1,2,6,7,8,9 (2,8): (3,8):1,2,4,6,7,8,9 (4,8):1,2,3,4,6,7,8,9 (5,8):1,2,3,4,6,7,8,9 (6,8):1,2,3,4,6,7,8,9 (7,8):1,2,3,4,6,7,8,9 (8,8):1,2,3,4,6,7,8,9 (9,8):1,2,3,4,6,7,8,9
|
|
|
- (1,9):1,2,6,7,8,9 (2,9):1,4,6,7,8,9 (3,9):1,2,4,6,7,8,9 (4,9):1,2,3,4,5,6,7,8,9 (5,9):1,2,3,4,5,6,7,8,9 (6,9):1,2,3,4,5,6,7,8,9 (7,9):1,2,3,4,5,6,7,8,9 (8,9):1,2,3,4,5,6,7,8,9 (9,9):1,2,3,4,5,6,7,8,9
|
|
|
+ (1,1):1,6,7,8,9 (2,1): (3,1):1,4,6,7,8,9 (4,1):1,3,4,5,6,7,8,9 (5,1):1,3,4,5,6,7,8,9 (6,1):1,3,4,5,6,7,8,9 (7,1):1,3,4,5,6,7,8,9 (8,1):1,3,4,5,6,7,8,9 (9,1):1,3,4,5,6,7,8,9
|
|
|
+ (1,2):1,6,7,8,9 (2,2):1,4,6,7,8,9 (3,2): (4,2):1,2,4,5,6,7,8,9 (5,2):1,2,4,5,6,7,8,9 (6,2):1,2,4,5,6,7,8,9 (7,2):1,2,4,5,6,7,8,9 (8,2):1,2,4,5,6,7,8,9 (9,2):1,2,4,5,6,7,8,9
|
|
|
+ (1,3):1,6,7,8,9 (2,3):1,4,6,7,8,9 (3,3): (4,3):1,2,3,4,6,7,8,9 (5,3):1,2,3,4,6,7,8,9 (6,3):1,2,3,4,6,7,8,9 (7,3):1,2,3,4,6,7,8,9 (8,3):1,2,3,4,6,7,8,9 (9,3):1,2,3,4,6,7,8,9
|
|
|
+ (1,4):3,5 (2,4):1,6,7,8,9 (3,4):1,2,6,7,8,9 (4,4):1,2,3,4,5,6,7,8,9 (5,4):1,2,3,4,5,6,7,8,9 (6,4):1,2,3,4,5,6,7,8,9 (7,4):1,2,3,4,5,6,7,8,9 (8,4):1,2,3,4,5,6,7,8,9 (9,4):1,2,3,4,5,6,7,8,9
|
|
|
+ (1,5): (2,5):1,6,7,8,9 (3,5):1,2,6,7,8,9 (4,5):1,2,3,5,6,7,8,9 (5,5):1,2,3,5,6,7,8,9 (6,5):1,2,3,5,6,7,8,9 (7,5):1,2,3,5,6,7,8,9 (8,5):1,2,3,5,6,7,8,9 (9,5):1,2,3,5,6,7,8,9
|
|
|
+ (1,6):3,5 (2,6):1,6,7,8,9 (3,6):1,2,6,7,8,9 (4,6):1,2,3,4,5,6,7,8,9 (5,6):1,2,3,4,5,6,7,8,9 (6,6):1,2,3,4,5,6,7,8,9 (7,6):1,2,3,4,5,6,7,8,9 (8,6):1,2,3,4,5,6,7,8,9 (9,6):1,2,3,4,5,6,7,8,9
|
|
|
+ (1,7):1,2,6,7,8,9 (2,7): (3,7):1,2,4,6,7,8,9 (4,7):1,2,4,5,6,7,8,9 (5,7):1,2,4,5,6,7,8,9 (6,7):1,2,4,5,6,7,8,9 (7,7):1,2,4,5,6,7,8,9 (8,7):1,2,4,5,6,7,8,9 (9,7):1,2,4,5,6,7,8,9
|
|
|
+ (1,8):1,2,6,7,8,9 (2,8): (3,8):1,2,4,6,7,8,9 (4,8):1,2,3,4,6,7,8,9 (5,8):1,2,3,4,6,7,8,9 (6,8):1,2,3,4,6,7,8,9 (7,8):1,2,3,4,6,7,8,9 (8,8):1,2,3,4,6,7,8,9 (9,8):1,2,3,4,6,7,8,9
|
|
|
+ (1,9):1,2,6,7,8,9 (2,9):1,4,6,7,8,9 (3,9):1,2,4,6,7,8,9 (4,9):1,2,3,4,5,6,7,8,9 (5,9):1,2,3,4,5,6,7,8,9 (6,9):1,2,3,4,5,6,7,8,9 (7,9):1,2,3,4,5,6,7,8,9 (8,9):1,2,3,4,5,6,7,8,9 (9,9):1,2,3,4,5,6,7,8,9
|
|
|
|
|
|
^ This shows that find_pairs is working!
|
|
|
- finalize - should see that 2 is only possible in (1,7), (1,8), and (1,9)
|
|
|
+ finalize - should see that 2 is only possible in (1,7), (1,8), and (1,9)
|
|
|
// OK! find_pairs does work (making the changes) - so I do need to call it, sometime.
|
|
|
and not in (3,7), (3,8) and (3,9).
|
|
|
*/
|
|
@@ -2054,7 +2136,7 @@ mod tests {
|
|
|
// Running just this test:
|
|
|
// cargo test -p sudoku logic_test_triple -- --ignored --show-output
|
|
|
|
|
|
- #[ignore]
|
|
|
+ #[ignore = "Finalized not completed (NNY!)"]
|
|
|
#[test]
|
|
|
fn logic_test_triple() {
|
|
|
let mut board = AnyBoard::new(3);
|
|
@@ -2133,7 +2215,7 @@ mod tests {
|
|
|
]
|
|
|
);
|
|
|
|
|
|
- // board.display();
|
|
|
+ board.display();
|
|
|
let mut solver = AnySolver::new_from(&board);
|
|
|
assert!(solver.validate_board());
|
|
|
|
|
@@ -2142,6 +2224,7 @@ mod tests {
|
|
|
if !solver.solve_logic() {
|
|
|
solver.board.display();
|
|
|
}
|
|
|
+ solver.board.display();
|
|
|
|
|
|
/*
|
|
|
╔═══╦═══╦═══╗
|
|
@@ -2202,7 +2285,7 @@ mod tests {
|
|
|
"FM L H P "
|
|
|
]
|
|
|
);
|
|
|
- // board.display();
|
|
|
+ board.display();
|
|
|
|
|
|
let mut solver = AnySolver::new_from(&board);
|
|
|
assert!(solver.validate_board());
|
|
@@ -2210,6 +2293,8 @@ mod tests {
|
|
|
if !solver.solve_logic() {
|
|
|
solver.board.display();
|
|
|
}
|
|
|
+ solver.board.display();
|
|
|
+
|
|
|
/*
|
|
|
solver.board.display();
|
|
|
╔════╦════╦════╦════╗
|
|
@@ -2262,7 +2347,7 @@ mod tests {
|
|
|
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_");
|
|
|
assert!(result.is_ok());
|
|
|
- // board.display();
|
|
|
+ board.display();
|
|
|
let strings: Vec<String> = board.to_strings();
|
|
|
assert_eq!(
|
|
|
strings,
|
|
@@ -2303,6 +2388,7 @@ mod tests {
|
|
|
}
|
|
|
assert!(solver.validate_board());
|
|
|
assert!(solver.board.complete());
|
|
|
+ solver.board.display();
|
|
|
|
|
|
/*
|
|
|
solver.board.display();
|