group.rs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. use std::fmt;
  2. // load sudoku
  3. use crate::*;
  4. /// Width of the sudoku board.
  5. const WIDTH: u8 = 9;
  6. // /// Size (width * height) of the board.
  7. // const MAX_SIZE: u8 = 81;
  8. // #[derive(Debug)]
  9. /// Define a Group of sudoku positions.
  10. /// This defines rows, columns, and cells for analysis.
  11. #[derive(PartialEq)]
  12. pub struct Group(pub [u8; WIDTH as usize]);
  13. /*
  14. pub struct Group {
  15. pub items: [u8; WIDTH as usize],
  16. }
  17. */
  18. /// Group of positions for rows.
  19. const GROUP_ROW: [Group; 9] = [
  20. Group([
  21. pos1(1, 1),
  22. pos1(2, 1),
  23. pos1(3, 1),
  24. pos1(4, 1),
  25. pos1(5, 1),
  26. pos1(6, 1),
  27. pos1(7, 1),
  28. pos1(8, 1),
  29. pos1(9, 1),
  30. ]),
  31. Group([
  32. pos1(1, 2),
  33. pos1(2, 2),
  34. pos1(3, 2),
  35. pos1(4, 2),
  36. pos1(5, 2),
  37. pos1(6, 2),
  38. pos1(7, 2),
  39. pos1(8, 2),
  40. pos1(9, 2),
  41. ]),
  42. Group([
  43. pos1(1, 3),
  44. pos1(2, 3),
  45. pos1(3, 3),
  46. pos1(4, 3),
  47. pos1(5, 3),
  48. pos1(6, 3),
  49. pos1(7, 3),
  50. pos1(8, 3),
  51. pos1(9, 3),
  52. ]),
  53. Group([
  54. pos1(1, 4),
  55. pos1(2, 4),
  56. pos1(3, 4),
  57. pos1(4, 4),
  58. pos1(5, 4),
  59. pos1(6, 4),
  60. pos1(7, 4),
  61. pos1(8, 4),
  62. pos1(9, 4),
  63. ]),
  64. Group([
  65. pos1(1, 5),
  66. pos1(2, 5),
  67. pos1(3, 5),
  68. pos1(4, 5),
  69. pos1(5, 5),
  70. pos1(6, 5),
  71. pos1(7, 5),
  72. pos1(8, 5),
  73. pos1(9, 5),
  74. ]),
  75. Group([
  76. pos1(1, 6),
  77. pos1(2, 6),
  78. pos1(3, 6),
  79. pos1(4, 6),
  80. pos1(5, 6),
  81. pos1(6, 6),
  82. pos1(7, 6),
  83. pos1(8, 6),
  84. pos1(9, 6),
  85. ]),
  86. Group([
  87. pos1(1, 7),
  88. pos1(2, 7),
  89. pos1(3, 7),
  90. pos1(4, 7),
  91. pos1(5, 7),
  92. pos1(6, 7),
  93. pos1(7, 7),
  94. pos1(8, 7),
  95. pos1(9, 7),
  96. ]),
  97. Group([
  98. pos1(1, 8),
  99. pos1(2, 8),
  100. pos1(3, 8),
  101. pos1(4, 8),
  102. pos1(5, 8),
  103. pos1(6, 8),
  104. pos1(7, 8),
  105. pos1(8, 8),
  106. pos1(9, 8),
  107. ]),
  108. Group([
  109. pos1(1, 9),
  110. pos1(2, 9),
  111. pos1(3, 9),
  112. pos1(4, 9),
  113. pos1(5, 9),
  114. pos1(6, 9),
  115. pos1(7, 9),
  116. pos1(8, 9),
  117. pos1(9, 9),
  118. ]),
  119. ];
  120. /// Group of positions for columns.
  121. const GROUP_COLUMN: [Group; 9] = [
  122. Group([
  123. pos1(1, 1),
  124. pos1(1, 2),
  125. pos1(1, 3),
  126. pos1(1, 4),
  127. pos1(1, 5),
  128. pos1(1, 6),
  129. pos1(1, 7),
  130. pos1(1, 8),
  131. pos1(1, 9),
  132. ]),
  133. Group([
  134. pos1(2, 1),
  135. pos1(2, 2),
  136. pos1(2, 3),
  137. pos1(2, 4),
  138. pos1(2, 5),
  139. pos1(2, 6),
  140. pos1(2, 7),
  141. pos1(2, 8),
  142. pos1(2, 9),
  143. ]),
  144. Group([
  145. pos1(3, 1),
  146. pos1(3, 2),
  147. pos1(3, 3),
  148. pos1(3, 4),
  149. pos1(3, 5),
  150. pos1(3, 6),
  151. pos1(3, 7),
  152. pos1(3, 8),
  153. pos1(3, 9),
  154. ]),
  155. Group([
  156. pos1(4, 1),
  157. pos1(4, 2),
  158. pos1(4, 3),
  159. pos1(4, 4),
  160. pos1(4, 5),
  161. pos1(4, 6),
  162. pos1(4, 7),
  163. pos1(4, 8),
  164. pos1(4, 9),
  165. ]),
  166. Group([
  167. pos1(5, 1),
  168. pos1(5, 2),
  169. pos1(5, 3),
  170. pos1(5, 4),
  171. pos1(5, 5),
  172. pos1(5, 6),
  173. pos1(5, 7),
  174. pos1(5, 8),
  175. pos1(5, 9),
  176. ]),
  177. Group([
  178. pos1(6, 1),
  179. pos1(6, 2),
  180. pos1(6, 3),
  181. pos1(6, 4),
  182. pos1(6, 5),
  183. pos1(6, 6),
  184. pos1(6, 7),
  185. pos1(6, 8),
  186. pos1(6, 9),
  187. ]),
  188. Group([
  189. pos1(7, 1),
  190. pos1(7, 2),
  191. pos1(7, 3),
  192. pos1(7, 4),
  193. pos1(7, 5),
  194. pos1(7, 6),
  195. pos1(7, 7),
  196. pos1(7, 8),
  197. pos1(7, 9),
  198. ]),
  199. Group([
  200. pos1(8, 1),
  201. pos1(8, 2),
  202. pos1(8, 3),
  203. pos1(8, 4),
  204. pos1(8, 5),
  205. pos1(8, 6),
  206. pos1(8, 7),
  207. pos1(8, 8),
  208. pos1(8, 9),
  209. ]),
  210. Group([
  211. pos1(9, 1),
  212. pos1(9, 2),
  213. pos1(9, 3),
  214. pos1(9, 4),
  215. pos1(9, 5),
  216. pos1(9, 6),
  217. pos1(9, 7),
  218. pos1(9, 8),
  219. pos1(9, 9),
  220. ]),
  221. ];
  222. /// Group of positions for cells (3x3 grid).
  223. const GROUP_CELL: [Group; 9] = [
  224. Group([
  225. pos1(1, 1),
  226. pos1(2, 1),
  227. pos1(3, 1),
  228. pos1(1, 2),
  229. pos1(2, 2),
  230. pos1(3, 2),
  231. pos1(1, 3),
  232. pos1(2, 3),
  233. pos1(3, 3),
  234. ]),
  235. Group([
  236. pos1(4, 1),
  237. pos1(5, 1),
  238. pos1(6, 1),
  239. pos1(4, 2),
  240. pos1(5, 2),
  241. pos1(6, 2),
  242. pos1(4, 3),
  243. pos1(5, 3),
  244. pos1(6, 3),
  245. ]),
  246. Group([
  247. pos1(7, 1),
  248. pos1(8, 1),
  249. pos1(9, 1),
  250. pos1(7, 2),
  251. pos1(8, 2),
  252. pos1(9, 2),
  253. pos1(7, 3),
  254. pos1(8, 3),
  255. pos1(9, 3),
  256. ]),
  257. Group([
  258. pos1(1, 4),
  259. pos1(2, 4),
  260. pos1(3, 4),
  261. pos1(1, 5),
  262. pos1(2, 5),
  263. pos1(3, 5),
  264. pos1(1, 6),
  265. pos1(2, 6),
  266. pos1(3, 6),
  267. ]),
  268. Group([
  269. pos1(4, 4),
  270. pos1(5, 4),
  271. pos1(6, 4),
  272. pos1(4, 5),
  273. pos1(5, 5),
  274. pos1(6, 5),
  275. pos1(4, 6),
  276. pos1(5, 6),
  277. pos1(6, 6),
  278. ]),
  279. Group([
  280. pos1(7, 4),
  281. pos1(8, 4),
  282. pos1(9, 4),
  283. pos1(7, 5),
  284. pos1(8, 5),
  285. pos1(9, 5),
  286. pos1(7, 6),
  287. pos1(8, 6),
  288. pos1(9, 6),
  289. ]),
  290. Group([
  291. pos1(1, 7),
  292. pos1(2, 7),
  293. pos1(3, 7),
  294. pos1(1, 8),
  295. pos1(2, 8),
  296. pos1(3, 8),
  297. pos1(1, 9),
  298. pos1(2, 9),
  299. pos1(3, 9),
  300. ]),
  301. Group([
  302. pos1(4, 7),
  303. pos1(5, 7),
  304. pos1(6, 7),
  305. pos1(4, 8),
  306. pos1(5, 8),
  307. pos1(6, 8),
  308. pos1(4, 9),
  309. pos1(5, 9),
  310. pos1(6, 9),
  311. ]),
  312. Group([
  313. pos1(7, 7),
  314. pos1(8, 7),
  315. pos1(9, 7),
  316. pos1(7, 8),
  317. pos1(8, 8),
  318. pos1(9, 8),
  319. pos1(7, 9),
  320. pos1(8, 9),
  321. pos1(9, 9),
  322. ]),
  323. ];
  324. impl fmt::Debug for Group {
  325. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  326. if f.alternate() {
  327. write!(f, "Group {{ {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}] }}",
  328. self.0[0], xy(self.0[0]).0, xy(self.0[0]).1,
  329. self.0[1], xy(self.0[1]).0, xy(self.0[1]).1,
  330. self.0[2], xy(self.0[2]).0, xy(self.0[2]).1,
  331. self.0[3], xy(self.0[3]).0, xy(self.0[3]).1,
  332. self.0[4], xy(self.0[4]).0, xy(self.0[4]).1,
  333. self.0[5], xy(self.0[5]).0, xy(self.0[5]).1,
  334. self.0[6], xy(self.0[6]).0, xy(self.0[6]).1,
  335. self.0[7], xy(self.0[7]).0, xy(self.0[7]).1,
  336. self.0[8], xy(self.0[8]).0, xy(self.0[8]).1,
  337. )
  338. } else {
  339. f.debug_struct("Group").field("items", &self).finish()
  340. }
  341. }
  342. }
  343. pub fn for_column(x: u8) -> &'static Group {
  344. &GROUP_COLUMN[x as usize]
  345. }
  346. pub fn for_row(y: u8) -> &'static Group {
  347. &GROUP_ROW[y as usize]
  348. }
  349. pub fn for_cell(i: u8) -> &'static Group {
  350. &GROUP_CELL[i as usize]
  351. }
  352. /// Which cell contains this x,y?
  353. pub fn which_cell(x: u8, y: u8) -> u8 {
  354. (x / 3) + (y / 3) * 3
  355. }
  356. #[cfg(test)]
  357. mod tests {
  358. // use crate::sudoku::*;
  359. use crate::group::*;
  360. // use crate::sudoku::group::*;
  361. // use crate::Group;
  362. // use group::*;
  363. // use crate::{for_cell, for_column, for_row};
  364. #[test]
  365. fn check_columns() {
  366. let mut g = Group::new();
  367. for i in 0..9 {
  368. println!("Index={}", i);
  369. g.for_column(i, 1);
  370. let new_g = for_column(i);
  371. assert_eq!(g, *new_g);
  372. }
  373. }
  374. #[test]
  375. fn check_rows() {
  376. let mut g = Group::new();
  377. for i in 0..9 {
  378. println!("Index={}", i);
  379. g.for_row(1, i);
  380. let new_g = for_row(i);
  381. assert_eq!(g, *new_g);
  382. }
  383. }
  384. #[test]
  385. fn check_cells() {
  386. let mut g = Group::new();
  387. for i in 0..9 {
  388. println!("Index={}", i);
  389. g.for_block((i % 3) * 3, (i / 3) * 3);
  390. let new_g = for_cell(i);
  391. assert_eq!(g, *new_g);
  392. }
  393. }
  394. }
  395. impl Group {
  396. pub fn new() -> Self {
  397. Group([0; WIDTH as usize])
  398. }
  399. pub fn for_column(&mut self, x: u8, _y: u8) {
  400. for y in 0..WIDTH {
  401. self.0[y as usize] = pos(x, y);
  402. }
  403. }
  404. pub fn for_row(&mut self, _x: u8, y: u8) {
  405. for x in 0..WIDTH {
  406. self.0[x as usize] = pos(x, y);
  407. }
  408. }
  409. pub fn for_block(&mut self, x: u8, y: u8) {
  410. // Find starting block positions
  411. let sb_x = x - (x % 3);
  412. let sb_y = y - (y % 3);
  413. for i in 0..WIDTH {
  414. let ix = i % 3;
  415. let iy = i / 3;
  416. // println!("i = {}, sb.x = {} sb.y = {}, ix = {} iy = {}", i, sb_x, sb_y, ix, iy);
  417. self.0[i as usize] = pos(sb_x + ix, sb_y + iy);
  418. }
  419. }
  420. pub fn for_iter(&mut self, i: u8) {
  421. let sb_x = (i % 3) * 3;
  422. let sb_y = (i / 3) * 3;
  423. self.for_block(sb_x, sb_y);
  424. }
  425. pub fn display(&self) {
  426. for i in 0..WIDTH {
  427. let v = self.0[i as usize];
  428. print!("{} [{},{}] ", v, xy(v).0, xy(v).1);
  429. }
  430. println!("");
  431. }
  432. }