2 Commits 39f00dc04c ... ec9c317846

Tác giả SHA1 Thông báo Ngày
  Steve Thielemann ec9c317846 Added [] to other things, just because. 1 tháng trước cách đây
  Steve Thielemann b9e43ad1bd Silenced warnings in "working on" code. 1 tháng trước cách đây
2 tập tin đã thay đổi với 176 bổ sung49 xóa
  1. 35 0
      sudoku/src/bits.rs
  2. 141 49
      sudoku/src/sudoku.rs

+ 35 - 0
sudoku/src/bits.rs

@@ -126,6 +126,12 @@ impl fmt::Debug for GenBits {
         }
 }
 
+impl fmt::Display for GenBits {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "({})", self.0.iter().enumerate().filter(|x| *x.1).map(|x| x.0.to_string()).collect::<Vec<_>>().join(","))
+    }
+}
+
 impl PartialEq for GenBits {
     fn eq(&self, other: &Self) -> bool {
         if self.0.len() != other.0.len() {
@@ -140,6 +146,24 @@ impl PartialEq for GenBits {
     }
 }
 
+// Experiment: Add accessing by []
+
+use std::ops::{Index, IndexMut};
+
+impl Index<usize> for GenBits {
+    type Output = bool;
+
+    fn index<'a>(&'a self, i:usize) -> &'a bool {
+        &self.0[i]
+    }
+}
+
+impl IndexMut<usize> for GenBits {
+    fn index_mut<'a>(&'a mut self, i:usize) -> &'a mut bool {
+        &mut self.0[i]
+    }
+}
+
 #[cfg(test)]
 mod tests {
     // use crate::sudoku::*;
@@ -160,6 +184,17 @@ mod tests {
             assert_eq!(result, true);
         }
 
+        p.clear();
+
+        // Check access by []
+        for i in 0..9 {
+            let mut result = p[i];
+            assert_eq!(result, false);
+            p[i] =true;
+            result = p[i];
+            assert_eq!(result, true);
+        }
+
         p = GenBits::new(SIZE);
         p.set(3, true);
         p.set(5, true);

+ 141 - 49
sudoku/src/sudoku.rs

@@ -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 {
-            self.possible
+            let _ = self
+                .possible
                 .find_pairs(self.group.group(Groups::Cell, cell));
         }
 
@@ -878,9 +941,9 @@ impl AnySolver {
 
         // Scan rows/columns
         for cell in 0..width {
-            let cell_info = self.group.group(Groups::Cell, cell);
+            let _cell_info = self.group.group(Groups::Cell, cell);
 
-            for row in 0..size {}
+            for _row in 0..size {}
         }
     }
 
@@ -892,16 +955,18 @@ 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];
         cell_update[cell_index as usize] = true;
 
         let values = self.possible.find_value_pos();
-        println!("Values: {:?}", values);
+
+        // Not needed, displayed below (and only if not empty). ;)
+        // println!("Values: {:?}", values);
 
         for (value, positions) in values.iter().enumerate() {
             if positions.count_set() == 0 {
@@ -916,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...
@@ -931,7 +998,7 @@ impl AnySolver {
                 }
 
                 // rows go the entire width of the game...
-                for row in 0..width {}
+                for _row in 0..width {}
             }
         }
         /*
@@ -1027,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.
 
@@ -1059,8 +1128,8 @@ impl AnySolver {
 
             // println!("Value {} {:?} is needed {:?}", value + 1, all_cells, found);
 
-            for x in x_range.clone() {
-                for y in 0..width {
+            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);
@@ -1069,16 +1138,18 @@ impl AnySolver {
         }
 
         // Check rows
-        for value in 0..width {
-            for y in y_range.clone() {
-                for x in 0..width {
+        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...");
+        if NOISY {
+            println!("finalize_cell ends...");
+        }
     }
 
     /// Finalize move(s) on the board.
@@ -1097,6 +1168,7 @@ impl AnySolver {
             self.finalize_cell(idx + idx * self.board.size);
         }
         */
+        println!("TODO");
     }
 
     /// Validate the board
@@ -1819,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);
@@ -1828,7 +1912,8 @@ mod tests {
         board.set(0, 4, 4);
         board.set(0, 5, 5);
         board.display();
-        let mut solver = AnySolver::new_from(&board);
+
+        let solver = AnySolver::new_from(&board);
         /*
            ╔═══╦═══╦═══╗
            ║ 2 ║   ║   ║
@@ -1965,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);
@@ -1977,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();
@@ -2022,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).
          */
@@ -2048,7 +2133,10 @@ mod tests {
         // solver.possible.display();
     }
 
-    #[ignore]
+    // Running just this test:
+    // cargo test -p sudoku logic_test_triple -- --ignored --show-output
+
+    #[ignore = "Finalized not completed (NNY!)"]
     #[test]
     fn logic_test_triple() {
         let mut board = AnyBoard::new(3);
@@ -2127,7 +2215,7 @@ mod tests {
             ]
         );
 
-        // board.display();
+        board.display();
         let mut solver = AnySolver::new_from(&board);
         assert!(solver.validate_board());
 
@@ -2136,6 +2224,7 @@ mod tests {
         if !solver.solve_logic() {
             solver.board.display();
         }
+        solver.board.display();
 
         /*
         ╔═══╦═══╦═══╗
@@ -2196,7 +2285,7 @@ mod tests {
                 "FM  L    H    P "
             ]
         );
-        // board.display();
+        board.display();
 
         let mut solver = AnySolver::new_from(&board);
         assert!(solver.validate_board());
@@ -2204,6 +2293,8 @@ mod tests {
         if !solver.solve_logic() {
             solver.board.display();
         }
+        solver.board.display();
+
         /*
         solver.board.display();
         ╔════╦════╦════╦════╗
@@ -2256,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,
@@ -2297,6 +2388,7 @@ mod tests {
         }
         assert!(solver.validate_board());
         assert!(solver.board.complete());
+        solver.board.display();
 
         /*
         solver.board.display();