5 コミット 9b6ca50ea8 ... 29e635c3a5

作者 SHA1 メッセージ 日付
  Steve Thielemann 29e635c3a5 unsure. 1 ヶ月 前
  Steve Thielemann 01338576eb Working AnyPossible.find_pairs. 3 ヶ月 前
  Steve Thielemann 95cc267844 Working find_pairs, that does something now. 3 ヶ月 前
  Steve Thielemann eebe4ee636 Tests working again. 3 ヶ月 前
  Steve Thielemann 549f406da4 Making and saving working again. 4 ヶ月 前
7 ファイル変更838 行追加68 行削除
  1. 6 0
      Cargo.toml
  2. 14 20
      src/main.rs
  3. 7 0
      sudoku/Cargo.toml
  4. 19 1
      sudoku/src/bits.rs
  5. 34 4
      sudoku/src/group.rs
  6. 755 43
      sudoku/src/sudoku.rs
  7. 3 0
      test-out

+ 6 - 0
Cargo.toml

@@ -17,3 +17,9 @@ sudoku = { path = "sudoku" }
 # name = "benchmark"
 # harness = false
 
+[source.crates-io]
+replace-with = "vendored-sources"
+
+[source.vendored-sources]
+directory = "vendor"
+

+ 14 - 20
src/main.rs

@@ -38,36 +38,30 @@ fn main() {
 
     if args.get_flag("make") {
         let size: u8 = *args.get_one::<u8>("size").unwrap();
-        let mut s = AnySolver::new(size);
-
-        s.make();
-        s.board.display();
-        /*
-        s.make();
-        let mut p = s.clone();
-
-        // Ok, get working on the puzzle.
-        for _x in 0..81 {
-            while p.remove() {
-                print!("-");
-            }
+        let mut solution = AnySolver::new(size);
+
+        solution.make();
+        solution.board.display();
+        // 16x16 make_puzzle() takes too long.
+        let mut puzzle = solution.clone();
+        for _ in 0..81 {
+            puzzle.make_puzzle();
         }
-        println!("");
 
-        p.display();
-        println!("Solution:");
-        s.display();
         if let Some(filename) = args.get_one::<PathBuf>("file") {
             let mut ksudo = Ksudoku::default();
-            ksudo.puzzle = p.save_to_tld('b', '_');
-            ksudo.solution = s.save_to_tld('b', '_');
+            ksudo.puzzle = puzzle.board.save_ksudoku();
+            ksudo.solution = solution.board.save_ksudoku();
             ksudo.order = 9; // Defaults currently 3x3
             let r = save_ksudoku(filename.to_path_buf(), &ksudo);
             if r.is_ok() {
                 println!("Saved!");
             }
+        } else {
+            puzzle.board.display();
+            println!("Solution:");
+            solution.board.display();    
         }
-        */
         return;
     }
 

+ 7 - 0
sudoku/Cargo.toml

@@ -17,3 +17,10 @@ xml = "0.8.20"
 [lib]
 name = "sudoku"
 test = true
+
+[source.crates-io]
+replace-with = "vendored-sources"
+
+[source.vendored-sources]
+directory = "vendor"
+

+ 19 - 1
sudoku/src/bits.rs

@@ -5,8 +5,9 @@ use bit_field::BitField;
 
 use num::Integer;
 use std::ops::RangeBounds;
+use std::fmt;
 
-#[derive(Debug, Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub struct GenBits<T: Integer + BitField>(pub T);
 
 impl<T: Integer + BitField> GenBits<T> {
@@ -38,14 +39,31 @@ impl<T: Integer + BitField> GenBits<T> {
         count
     }
 
+    /// Display bits that are set.
+    /// +1 is added to the display, so it matches the cell values (1..N)
     pub fn display(&self) -> String {
         self.iter()
             .map(|i| (i+1).to_string())
+            // .map(|i| i.to_string())
             .collect::<Vec<_>>().join(",")
     }
 
 }
 
+impl<T: Integer + BitField + ToString> fmt::Debug for GenBits<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let result = self.iter()
+        // .map(|i| (i+1).to_string())
+        .map(|i| i.to_string())
+        .collect::<Vec<_>>().join(",");
+        if result.is_empty() {
+            return write!(f, "{{}}")
+        } else {
+        return write!(f, "<{}>", result)
+        }
+    }
+}
+
 pub struct GenBitsIterator<'a, T: Integer + BitField> {
     pub possible: &'a GenBits<T>,
     pub index: usize,

+ 34 - 4
sudoku/src/group.rs

@@ -112,6 +112,33 @@ impl AnyGroup {
         (x / self.size) + (y / self.size) * self.size
     }
 
+    /// Convert index to x,y offsets.
+    pub fn cell_offset(&self, idx:u8) -> (u8,u8) {
+        (idx % self.size, idx / self.size)
+    }
+    
+    /// Which index for given cell and (x,y)?
+    pub fn which_cell_index(&self, cell_index:u8, x:u8, y:u8) -> usize {
+        let (sx,sy) = self.cell_start(cell_index);
+        self.pos(sx + x, sy+y)
+    }
+
+    /// Where does a given cell index start?
+    pub fn cell_start(&self, cell_index:u8) -> (u8,u8) {
+        ((cell_index % self.size) * self.size, (cell_index/self.size) * self.size)
+    }
+
+    /// Return index of cell (x,y)
+    /// - This uses the groups to locate the index of the group.
+    pub fn cell_index(&self, index: u8, x: u8, y: u8) -> usize {
+        debug_assert!( x < self.size);
+        debug_assert!( y < self.size);
+        
+        let result: usize =
+            self.groups[Groups::Cell as usize][index as usize * self.width as usize];
+        result + (y * self.width + x) as usize
+    }
+
     pub fn calculate(&mut self) {
         for y in 0..self.width {
             for x in 0..self.width {
@@ -238,8 +265,6 @@ mod tests {
     /// Verify that each index (0..max_index) is defined in each group.
     /// - Verify that it is used, and only once.
     fn check_dynamic() {
-
-
         for size in 3..=5 {
             let g = AnyGroup::new(size);
             // g.display();
@@ -290,10 +315,9 @@ mod tests {
                         y + 1
                     );
                 }
-    
             }
 
-            /* 
+            /*
             all.fill(0);
             for idx in 0..g.width {
                 let grp = g.row(idx);
@@ -357,4 +381,10 @@ mod tests {
             */
         }
     }
+    #[test]
+    fn check_cells() {
+        let size = 3;
+        let g = AnyGroup::new(size);
+        assert_eq!(g.cell_index(0, 0, 0), 0);
+    }
 }

ファイルの差分が大きいため隠しています
+ 755 - 43
sudoku/src/sudoku.rs


+ 3 - 0
test-out

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+cargo test -p sudoku -- --show-output $*

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません