Jelajahi Sumber

Working on possible, tracking what's left.

I'm thinking of moving to a HashSet here.
Steve Thielemann 10 bulan lalu
induk
melakukan
88c18ec43a
1 mengubah file dengan 111 tambahan dan 67 penghapusan
  1. 111 67
      src/main.rs

+ 111 - 67
src/main.rs

@@ -1,6 +1,7 @@
 use serde_derive::{Deserialize, Serialize};
 use serde_xml_rs::{from_reader, from_str, to_string};
 
+use std::fmt;
 use std::fs::File;
 
 #[derive(Debug, Serialize, Deserialize, PartialEq)]
@@ -38,23 +39,33 @@ const MAX_SIZE: u8 = 81;
 #[derive(Debug)]
 struct Sudoku {
     board: [u8; MAX_SIZE as usize],
+    possible: [[u8; SIZE as usize]; MAX_SIZE as usize],
 }
 
+// Translate x,y to position in board.
 const fn pos(x: u8, y: u8) -> u8 {
     x + (y * SIZE as u8)
 }
 
+// Translate post to x,y in board.
+const fn xy(pos: u8) -> (u8, u8) {
+    ((pos % SIZE), (pos / SIZE))
+}
+
 impl Sudoku {
     fn new() -> Self {
         let s = Sudoku {
             board: [0; MAX_SIZE as usize],
+            // possible: [[0; SIZE as usize]; MAX_SIZE as usize],
+            possible: [[1, 2, 3, 4, 5, 6, 7, 8, 9]; MAX_SIZE as usize],
         };
-
         s
     }
+
     fn clear(&mut self) {
         for x in 0..MAX_SIZE {
             self.board[x as usize] = 0;
+            self.possible[x as usize] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
         }
     }
 
@@ -91,7 +102,7 @@ impl Sudoku {
             }
             println!("");
             if y % 3 == 2 {
-                if (y + 1 == SIZE) {
+                if y + 1 == SIZE {
                     println!("╚═══╩═══╩═══╝");
                 } else {
                     println!("╠═══╬═══╬═══╣");
@@ -99,82 +110,115 @@ impl Sudoku {
             }
         }
     }
+
+    fn display_possible(&self) {
+        for y in 0..SIZE {
+            for x in 0..SIZE {
+                print!("({},{}):", x, y);
+                for i in 0..SIZE {
+                    let pos = self.possible[pos(x, y) as usize][i as usize];
+                    if pos == 0 {
+                        print!(" ");
+                    } else {
+                        print!("{}", pos);
+                    }
+                }
+                print!(" ");
+            }
+            println!("");
+        }
+    }
 }
-/*
-const InRow: [u8; 81] = [1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, 2, 3, 4, 5, 6, 7, 8, 9,
-];
- */
-
-// rows, columns, and cells ?  (maybe?)
-// With the ability to know what RCC each item belongs?
 
-#[derive(Debug)]
-struct OnlyOne {
-    positions: [u8; SIZE as usize],
+// #[derive(Debug)]
+struct Group {
+    items: [u8; SIZE as usize],
 }
 
-const CELLS: [OnlyOne; 3] = [
-    OnlyOne {
-        positions: [
-            pos(1, 1),
-            pos(1, 2),
-            pos(1, 3),
-            pos(1, 4),
-            pos(1, 5),
-            pos(1, 6),
-            pos(1, 7),
-            pos(1, 8),
-            pos(1, 9),
-        ],
-    },
-    OnlyOne {
-        positions: [
-            pos(2, 1),
-            pos(2, 2),
-            pos(2, 3),
-            pos(2, 4),
-            pos(2, 5),
-            pos(2, 6),
-            pos(2, 7),
-            pos(2, 8),
-            pos(2, 9),
-        ],
-    },
-    OnlyOne {
-        positions: [
-            pos(3, 1),
-            pos(3, 2),
-            pos(3, 3),
-            pos(3, 4),
-            pos(3, 5),
-            pos(3, 6),
-            pos(3, 7),
-            pos(3, 8),
-            pos(3, 9),
-        ],
-    },
-];
-
-const POS1: OnlyOne = OnlyOne {
-    positions: [0, 1, 2, 3, 4, 5, 6, 7, 8],
-};
+impl fmt::Debug for Group {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if f.alternate() {
+            write!(f, "Group {{ {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}] }}",
+                self.items[0], xy(self.items[0]).0, xy(self.items[0]).1,
+                self.items[1], xy(self.items[1]).0, xy(self.items[1]).1,
+                self.items[2], xy(self.items[2]).0, xy(self.items[2]).1,
+                self.items[3], xy(self.items[3]).0, xy(self.items[3]).1,
+                self.items[4], xy(self.items[4]).0, xy(self.items[4]).1,
+                self.items[5], xy(self.items[5]).0, xy(self.items[5]).1,
+                self.items[6], xy(self.items[6]).0, xy(self.items[6]).1,
+                self.items[7], xy(self.items[7]).0, xy(self.items[7]).1,
+                self.items[8], xy(self.items[8]).0, xy(self.items[8]).1,
+            )
+        } else {
+            f.debug_struct("Group").field("items", &self.items).finish()
+        }
+    }
+}
+
+impl Group {
+    fn new() -> Self {
+        Group {
+            items: [0; SIZE as usize],
+        }
+    }
+
+    fn for_column(&mut self, x: u8, _y: u8) {
+        for y in 0..SIZE {
+            self.items[y as usize] = pos(x, y);
+        }
+    }
+    fn for_row(&mut self, _x: u8, y: u8) {
+        for x in 0..SIZE {
+            self.items[x as usize] = pos(x, y);
+        }
+    }
+    fn for_block(&mut self, x: u8, y: u8) {
+        // Find starting block positions
+        let sb_x = x - (x % 3);
+        let sb_y = y - (y % 3);
+        for i in 0..SIZE {
+            let ix = i % 3;
+            let iy = i / 3;
+            // println!("i = {}, sb.x = {} sb.y = {}, ix = {} iy = {}", i, sb_x, sb_y, ix, iy);
+            self.items[i as usize] = pos(sb_x + ix, sb_y + iy);
+        }
+    }
+
+    fn display(&self) {
+        for i in 0..SIZE {
+            let v = self.items[i as usize];
+            print!("{} [{},{}] ", v, xy(v).0, xy(v).1);
+        }
+        println!("");
+    }
+}
 
 fn main() {
     let filename = "../puzzle1";
     let fh = File::open(filename).unwrap();
-
     let puzzle: Ksudoku = from_reader(fh).unwrap();
-
     println!("Puzzle: {:?}", puzzle);
-    println!("CELLS: {:?}", CELLS);
+
     let mut s = Sudoku::new();
     s.load_xsudoku(&puzzle.game.puzzle.values);
     s.display();
+    s.display_possible();
+
+    let mut g = Group::new();
+    g.for_row(1, 1);
+    print!("Row: ");
+    println!("{:?}", g);
+    println!("{:#?}", g);
+    // g.display();
+    print!("Col: ");
+    g.for_column(1, 1);
+    println!("{:?}", g);
+    // g.display();
+    println!("Blk testing output: ");
+
+    for i in 0..SIZE {
+        g.for_block(i, i);
+        println!("({},{} {:#?})", i, i, g);
+        // g.display();
+    }
 }