|
@@ -1,6 +1,7 @@
|
|
use serde_derive::{Deserialize, Serialize};
|
|
use serde_derive::{Deserialize, Serialize};
|
|
use serde_xml_rs::{from_reader, from_str, to_string};
|
|
use serde_xml_rs::{from_reader, from_str, to_string};
|
|
|
|
|
|
|
|
+use std::fmt;
|
|
use std::fs::File;
|
|
use std::fs::File;
|
|
|
|
|
|
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
|
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
|
@@ -38,23 +39,33 @@ const MAX_SIZE: u8 = 81;
|
|
#[derive(Debug)]
|
|
#[derive(Debug)]
|
|
struct Sudoku {
|
|
struct Sudoku {
|
|
board: [u8; MAX_SIZE as usize],
|
|
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 {
|
|
const fn pos(x: u8, y: u8) -> u8 {
|
|
x + (y * SIZE as 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 {
|
|
impl Sudoku {
|
|
fn new() -> Self {
|
|
fn new() -> Self {
|
|
let s = Sudoku {
|
|
let s = Sudoku {
|
|
board: [0; MAX_SIZE as usize],
|
|
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
|
|
s
|
|
}
|
|
}
|
|
|
|
+
|
|
fn clear(&mut self) {
|
|
fn clear(&mut self) {
|
|
for x in 0..MAX_SIZE {
|
|
for x in 0..MAX_SIZE {
|
|
self.board[x as usize] = 0;
|
|
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!("");
|
|
println!("");
|
|
if y % 3 == 2 {
|
|
if y % 3 == 2 {
|
|
- if (y + 1 == SIZE) {
|
|
|
|
|
|
+ if y + 1 == SIZE {
|
|
println!("╚═══╩═══╩═══╝");
|
|
println!("╚═══╩═══╩═══╝");
|
|
} else {
|
|
} else {
|
|
println!("╠═══╬═══╬═══╣");
|
|
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() {
|
|
fn main() {
|
|
let filename = "../puzzle1";
|
|
let filename = "../puzzle1";
|
|
let fh = File::open(filename).unwrap();
|
|
let fh = File::open(filename).unwrap();
|
|
-
|
|
|
|
let puzzle: Ksudoku = from_reader(fh).unwrap();
|
|
let puzzle: Ksudoku = from_reader(fh).unwrap();
|
|
-
|
|
|
|
println!("Puzzle: {:?}", puzzle);
|
|
println!("Puzzle: {:?}", puzzle);
|
|
- println!("CELLS: {:?}", CELLS);
|
|
|
|
|
|
+
|
|
let mut s = Sudoku::new();
|
|
let mut s = Sudoku::new();
|
|
s.load_xsudoku(&puzzle.game.puzzle.values);
|
|
s.load_xsudoku(&puzzle.game.puzzle.values);
|
|
s.display();
|
|
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();
|
|
|
|
+ }
|
|
}
|
|
}
|