main.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. use serde_derive::{Deserialize, Serialize};
  2. use serde_xml_rs::{from_reader, from_str, to_string};
  3. use std::fmt;
  4. use std::fs::File;
  5. #[derive(Debug, Serialize, Deserialize, PartialEq)]
  6. struct Graph {
  7. order: i32,
  8. #[serde(rename = "type")]
  9. game_type: String,
  10. #[serde(rename = "specific-type")]
  11. specific_type: String,
  12. }
  13. #[derive(Debug, Serialize, Deserialize, PartialEq)]
  14. struct Puzzle {
  15. graph: Graph,
  16. values: String,
  17. solution: String,
  18. }
  19. #[derive(Debug, Serialize, Deserialize, PartialEq)]
  20. struct Game {
  21. #[serde(rename = "had-help")]
  22. help: i16,
  23. #[serde(rename = "msecs-elapsed")]
  24. elapsed: u32,
  25. puzzle: Puzzle,
  26. }
  27. #[derive(Debug, Serialize, Deserialize, PartialEq)]
  28. struct Ksudoku {
  29. game: Game,
  30. }
  31. const SIZE: u8 = 9;
  32. const MAX_SIZE: u8 = 81;
  33. #[derive(Debug)]
  34. struct Sudoku {
  35. board: [u8; MAX_SIZE as usize],
  36. possible: [[u8; SIZE as usize]; MAX_SIZE as usize],
  37. }
  38. // Translate x,y to position in board.
  39. const fn pos(x: u8, y: u8) -> u8 {
  40. x + (y * SIZE as u8)
  41. }
  42. // Translate post to x,y in board.
  43. const fn xy(pos: u8) -> (u8, u8) {
  44. ((pos % SIZE), (pos / SIZE))
  45. }
  46. impl Sudoku {
  47. fn new() -> Self {
  48. let s = Sudoku {
  49. board: [0; MAX_SIZE as usize],
  50. // possible: [[0; SIZE as usize]; MAX_SIZE as usize],
  51. possible: [[1, 2, 3, 4, 5, 6, 7, 8, 9]; MAX_SIZE as usize],
  52. };
  53. s
  54. }
  55. fn clear(&mut self) {
  56. for x in 0..MAX_SIZE {
  57. self.board[x as usize] = 0;
  58. self.possible[x as usize] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  59. }
  60. }
  61. fn load_xsudoku(&mut self, s: &str) {
  62. self.clear();
  63. let mut x: u8 = 0;
  64. let mut y: u8 = 0;
  65. for ch in s.chars() {
  66. if ch >= 'b' {
  67. self.board[pos(x, y) as usize] = ch as u8 - 'a' as u8;
  68. };
  69. y += 1;
  70. if y >= SIZE {
  71. y = 0;
  72. x += 1;
  73. }
  74. }
  75. }
  76. fn display(&self) {
  77. println!("╔═══╦═══╦═══╗");
  78. for y in 0..SIZE {
  79. print!("║");
  80. for x in 0..SIZE {
  81. let item = self.board[pos(x as u8, y as u8) as usize];
  82. if item == 0 {
  83. print!(" ");
  84. } else if (item >= 1) && (item <= 9) {
  85. print!("{}", item);
  86. }
  87. if x % 3 == 2 {
  88. print!("║");
  89. }
  90. }
  91. println!("");
  92. if y % 3 == 2 {
  93. if y + 1 == SIZE {
  94. println!("╚═══╩═══╩═══╝");
  95. } else {
  96. println!("╠═══╬═══╬═══╣");
  97. }
  98. }
  99. }
  100. }
  101. fn display_possible(&self) {
  102. for y in 0..SIZE {
  103. for x in 0..SIZE {
  104. print!("({},{}):", x, y);
  105. for i in 0..SIZE {
  106. let pos = self.possible[pos(x, y) as usize][i as usize];
  107. if pos == 0 {
  108. print!(" ");
  109. } else {
  110. print!("{}", pos);
  111. }
  112. }
  113. print!(" ");
  114. }
  115. println!("");
  116. }
  117. }
  118. }
  119. // #[derive(Debug)]
  120. struct Group {
  121. items: [u8; SIZE as usize],
  122. }
  123. impl fmt::Debug for Group {
  124. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  125. if f.alternate() {
  126. write!(f, "Group {{ {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}] }}",
  127. self.items[0], xy(self.items[0]).0, xy(self.items[0]).1,
  128. self.items[1], xy(self.items[1]).0, xy(self.items[1]).1,
  129. self.items[2], xy(self.items[2]).0, xy(self.items[2]).1,
  130. self.items[3], xy(self.items[3]).0, xy(self.items[3]).1,
  131. self.items[4], xy(self.items[4]).0, xy(self.items[4]).1,
  132. self.items[5], xy(self.items[5]).0, xy(self.items[5]).1,
  133. self.items[6], xy(self.items[6]).0, xy(self.items[6]).1,
  134. self.items[7], xy(self.items[7]).0, xy(self.items[7]).1,
  135. self.items[8], xy(self.items[8]).0, xy(self.items[8]).1,
  136. )
  137. } else {
  138. f.debug_struct("Group").field("items", &self.items).finish()
  139. }
  140. }
  141. }
  142. impl Group {
  143. fn new() -> Self {
  144. Group {
  145. items: [0; SIZE as usize],
  146. }
  147. }
  148. fn for_column(&mut self, x: u8, _y: u8) {
  149. for y in 0..SIZE {
  150. self.items[y as usize] = pos(x, y);
  151. }
  152. }
  153. fn for_row(&mut self, _x: u8, y: u8) {
  154. for x in 0..SIZE {
  155. self.items[x as usize] = pos(x, y);
  156. }
  157. }
  158. fn for_block(&mut self, x: u8, y: u8) {
  159. // Find starting block positions
  160. let sb_x = x - (x % 3);
  161. let sb_y = y - (y % 3);
  162. for i in 0..SIZE {
  163. let ix = i % 3;
  164. let iy = i / 3;
  165. // println!("i = {}, sb.x = {} sb.y = {}, ix = {} iy = {}", i, sb_x, sb_y, ix, iy);
  166. self.items[i as usize] = pos(sb_x + ix, sb_y + iy);
  167. }
  168. }
  169. fn display(&self) {
  170. for i in 0..SIZE {
  171. let v = self.items[i as usize];
  172. print!("{} [{},{}] ", v, xy(v).0, xy(v).1);
  173. }
  174. println!("");
  175. }
  176. }
  177. fn main() {
  178. let filename = "../puzzle1";
  179. let fh = File::open(filename).unwrap();
  180. let puzzle: Ksudoku = from_reader(fh).unwrap();
  181. println!("Puzzle: {:?}", puzzle);
  182. let mut s = Sudoku::new();
  183. s.load_xsudoku(&puzzle.game.puzzle.values);
  184. s.display();
  185. s.display_possible();
  186. let mut g = Group::new();
  187. g.for_row(1, 1);
  188. print!("Row: ");
  189. println!("{:?}", g);
  190. println!("{:#?}", g);
  191. // g.display();
  192. print!("Col: ");
  193. g.for_column(1, 1);
  194. println!("{:?}", g);
  195. // g.display();
  196. println!("Blk testing output: ");
  197. for i in 0..SIZE {
  198. g.for_block(i, i);
  199. println!("({},{} {:#?})", i, i, g);
  200. // g.display();
  201. }
  202. }