4
0

5 کامیت‌ها 9b6ca50ea8 ... 29e635c3a5

نویسنده SHA1 پیام تاریخ
  Steve Thielemann 29e635c3a5 unsure. 8 ماه پیش
  Steve Thielemann 01338576eb Working AnyPossible.find_pairs. 10 ماه پیش
  Steve Thielemann 95cc267844 Working find_pairs, that does something now. 10 ماه پیش
  Steve Thielemann eebe4ee636 Tests working again. 10 ماه پیش
  Steve Thielemann 549f406da4 Making and saving working again. 11 ماه پیش
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 $*

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است