123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- 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)]
- struct Graph {
- order: i32,
- #[serde(rename = "type")]
- game_type: String,
- #[serde(rename = "specific-type")]
- specific_type: String,
- }
- #[derive(Debug, Serialize, Deserialize, PartialEq)]
- struct Puzzle {
- graph: Graph,
- values: String,
- solution: String,
- }
- #[derive(Debug, Serialize, Deserialize, PartialEq)]
- struct Game {
- #[serde(rename = "had-help")]
- help: i16,
- #[serde(rename = "msecs-elapsed")]
- elapsed: u32,
- puzzle: Puzzle,
- }
- #[derive(Debug, Serialize, Deserialize, PartialEq)]
- struct Ksudoku {
- game: Game,
- }
- const SIZE: u8 = 9;
- 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];
- }
- }
- fn load_xsudoku(&mut self, s: &str) {
- self.clear();
- let mut x: u8 = 0;
- let mut y: u8 = 0;
- for ch in s.chars() {
- if ch >= 'b' {
- self.board[pos(x, y) as usize] = ch as u8 - 'a' as u8;
- };
- y += 1;
- if y >= SIZE {
- y = 0;
- x += 1;
- }
- }
- }
- fn display(&self) {
- println!("╔═══╦═══╦═══╗");
- for y in 0..SIZE {
- print!("║");
- for x in 0..SIZE {
- let item = self.board[pos(x as u8, y as u8) as usize];
- if item == 0 {
- print!(" ");
- } else if (item >= 1) && (item <= 9) {
- print!("{}", item);
- }
- if x % 3 == 2 {
- print!("║");
- }
- }
- println!("");
- if y % 3 == 2 {
- if y + 1 == SIZE {
- println!("╚═══╩═══╩═══╝");
- } else {
- println!("╠═══╬═══╬═══╣");
- }
- }
- }
- }
- 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!("");
- }
- }
- }
- // #[derive(Debug)]
- struct Group {
- items: [u8; SIZE as usize],
- }
- 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);
- 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();
- }
- }
|