123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- use std::fmt;
- // load sudoku
- use crate::*;
- /// Width of the sudoku board.
- const WIDTH: u8 = 9;
- // /// Size (width * height) of the board.
- // const MAX_SIZE: u8 = 81;
- // #[derive(Debug)]
- /// Define a Group of sudoku positions.
- /// This defines rows, columns, and cells for analysis.
- #[derive(PartialEq)]
- pub struct Group(pub [u8; WIDTH as usize]);
- /*
- pub struct Group {
- pub items: [u8; WIDTH as usize],
- }
- */
- /// Group of positions for rows.
- const GROUP_ROW: [Group; 9] = [
- Group([
- pos1(1, 1),
- pos1(2, 1),
- pos1(3, 1),
- pos1(4, 1),
- pos1(5, 1),
- pos1(6, 1),
- pos1(7, 1),
- pos1(8, 1),
- pos1(9, 1),
- ]),
- Group([
- pos1(1, 2),
- pos1(2, 2),
- pos1(3, 2),
- pos1(4, 2),
- pos1(5, 2),
- pos1(6, 2),
- pos1(7, 2),
- pos1(8, 2),
- pos1(9, 2),
- ]),
- Group([
- pos1(1, 3),
- pos1(2, 3),
- pos1(3, 3),
- pos1(4, 3),
- pos1(5, 3),
- pos1(6, 3),
- pos1(7, 3),
- pos1(8, 3),
- pos1(9, 3),
- ]),
- Group([
- pos1(1, 4),
- pos1(2, 4),
- pos1(3, 4),
- pos1(4, 4),
- pos1(5, 4),
- pos1(6, 4),
- pos1(7, 4),
- pos1(8, 4),
- pos1(9, 4),
- ]),
- Group([
- pos1(1, 5),
- pos1(2, 5),
- pos1(3, 5),
- pos1(4, 5),
- pos1(5, 5),
- pos1(6, 5),
- pos1(7, 5),
- pos1(8, 5),
- pos1(9, 5),
- ]),
- Group([
- pos1(1, 6),
- pos1(2, 6),
- pos1(3, 6),
- pos1(4, 6),
- pos1(5, 6),
- pos1(6, 6),
- pos1(7, 6),
- pos1(8, 6),
- pos1(9, 6),
- ]),
- Group([
- pos1(1, 7),
- pos1(2, 7),
- pos1(3, 7),
- pos1(4, 7),
- pos1(5, 7),
- pos1(6, 7),
- pos1(7, 7),
- pos1(8, 7),
- pos1(9, 7),
- ]),
- Group([
- pos1(1, 8),
- pos1(2, 8),
- pos1(3, 8),
- pos1(4, 8),
- pos1(5, 8),
- pos1(6, 8),
- pos1(7, 8),
- pos1(8, 8),
- pos1(9, 8),
- ]),
- Group([
- pos1(1, 9),
- pos1(2, 9),
- pos1(3, 9),
- pos1(4, 9),
- pos1(5, 9),
- pos1(6, 9),
- pos1(7, 9),
- pos1(8, 9),
- pos1(9, 9),
- ]),
- ];
- /// Group of positions for columns.
- const GROUP_COLUMN: [Group; 9] = [
- Group([
- pos1(1, 1),
- pos1(1, 2),
- pos1(1, 3),
- pos1(1, 4),
- pos1(1, 5),
- pos1(1, 6),
- pos1(1, 7),
- pos1(1, 8),
- pos1(1, 9),
- ]),
- Group([
- pos1(2, 1),
- pos1(2, 2),
- pos1(2, 3),
- pos1(2, 4),
- pos1(2, 5),
- pos1(2, 6),
- pos1(2, 7),
- pos1(2, 8),
- pos1(2, 9),
- ]),
- Group([
- pos1(3, 1),
- pos1(3, 2),
- pos1(3, 3),
- pos1(3, 4),
- pos1(3, 5),
- pos1(3, 6),
- pos1(3, 7),
- pos1(3, 8),
- pos1(3, 9),
- ]),
- Group([
- pos1(4, 1),
- pos1(4, 2),
- pos1(4, 3),
- pos1(4, 4),
- pos1(4, 5),
- pos1(4, 6),
- pos1(4, 7),
- pos1(4, 8),
- pos1(4, 9),
- ]),
- Group([
- pos1(5, 1),
- pos1(5, 2),
- pos1(5, 3),
- pos1(5, 4),
- pos1(5, 5),
- pos1(5, 6),
- pos1(5, 7),
- pos1(5, 8),
- pos1(5, 9),
- ]),
- Group([
- pos1(6, 1),
- pos1(6, 2),
- pos1(6, 3),
- pos1(6, 4),
- pos1(6, 5),
- pos1(6, 6),
- pos1(6, 7),
- pos1(6, 8),
- pos1(6, 9),
- ]),
- Group([
- pos1(7, 1),
- pos1(7, 2),
- pos1(7, 3),
- pos1(7, 4),
- pos1(7, 5),
- pos1(7, 6),
- pos1(7, 7),
- pos1(7, 8),
- pos1(7, 9),
- ]),
- Group([
- pos1(8, 1),
- pos1(8, 2),
- pos1(8, 3),
- pos1(8, 4),
- pos1(8, 5),
- pos1(8, 6),
- pos1(8, 7),
- pos1(8, 8),
- pos1(8, 9),
- ]),
- Group([
- pos1(9, 1),
- pos1(9, 2),
- pos1(9, 3),
- pos1(9, 4),
- pos1(9, 5),
- pos1(9, 6),
- pos1(9, 7),
- pos1(9, 8),
- pos1(9, 9),
- ]),
- ];
- /// Group of positions for cells (3x3 grid).
- const GROUP_CELL: [Group; 9] = [
- Group([
- pos1(1, 1),
- pos1(2, 1),
- pos1(3, 1),
- pos1(1, 2),
- pos1(2, 2),
- pos1(3, 2),
- pos1(1, 3),
- pos1(2, 3),
- pos1(3, 3),
- ]),
- Group([
- pos1(4, 1),
- pos1(5, 1),
- pos1(6, 1),
- pos1(4, 2),
- pos1(5, 2),
- pos1(6, 2),
- pos1(4, 3),
- pos1(5, 3),
- pos1(6, 3),
- ]),
- Group([
- pos1(7, 1),
- pos1(8, 1),
- pos1(9, 1),
- pos1(7, 2),
- pos1(8, 2),
- pos1(9, 2),
- pos1(7, 3),
- pos1(8, 3),
- pos1(9, 3),
- ]),
- Group([
- pos1(1, 4),
- pos1(2, 4),
- pos1(3, 4),
- pos1(1, 5),
- pos1(2, 5),
- pos1(3, 5),
- pos1(1, 6),
- pos1(2, 6),
- pos1(3, 6),
- ]),
- Group([
- pos1(4, 4),
- pos1(5, 4),
- pos1(6, 4),
- pos1(4, 5),
- pos1(5, 5),
- pos1(6, 5),
- pos1(4, 6),
- pos1(5, 6),
- pos1(6, 6),
- ]),
- Group([
- pos1(7, 4),
- pos1(8, 4),
- pos1(9, 4),
- pos1(7, 5),
- pos1(8, 5),
- pos1(9, 5),
- pos1(7, 6),
- pos1(8, 6),
- pos1(9, 6),
- ]),
- Group([
- pos1(1, 7),
- pos1(2, 7),
- pos1(3, 7),
- pos1(1, 8),
- pos1(2, 8),
- pos1(3, 8),
- pos1(1, 9),
- pos1(2, 9),
- pos1(3, 9),
- ]),
- Group([
- pos1(4, 7),
- pos1(5, 7),
- pos1(6, 7),
- pos1(4, 8),
- pos1(5, 8),
- pos1(6, 8),
- pos1(4, 9),
- pos1(5, 9),
- pos1(6, 9),
- ]),
- Group([
- pos1(7, 7),
- pos1(8, 7),
- pos1(9, 7),
- pos1(7, 8),
- pos1(8, 8),
- pos1(9, 8),
- pos1(7, 9),
- pos1(8, 9),
- pos1(9, 9),
- ]),
- ];
- impl fmt::Debug for Group {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- if f.alternate() {
- write!(f, "Group {{ {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}], {}[{},{}] }}",
- self.0[0], xy(self.0[0]).0, xy(self.0[0]).1,
- self.0[1], xy(self.0[1]).0, xy(self.0[1]).1,
- self.0[2], xy(self.0[2]).0, xy(self.0[2]).1,
- self.0[3], xy(self.0[3]).0, xy(self.0[3]).1,
- self.0[4], xy(self.0[4]).0, xy(self.0[4]).1,
- self.0[5], xy(self.0[5]).0, xy(self.0[5]).1,
- self.0[6], xy(self.0[6]).0, xy(self.0[6]).1,
- self.0[7], xy(self.0[7]).0, xy(self.0[7]).1,
- self.0[8], xy(self.0[8]).0, xy(self.0[8]).1,
- )
- } else {
- f.debug_struct("Group").field("items", &self).finish()
- }
- }
- }
- pub fn for_column(x: u8) -> &'static Group {
- &GROUP_COLUMN[x as usize]
- }
- pub fn for_row(y: u8) -> &'static Group {
- &GROUP_ROW[y as usize]
- }
- pub fn for_cell(i: u8) -> &'static Group {
- &GROUP_CELL[i as usize]
- }
- /// Which cell contains this x,y?
- pub fn which_cell(x: u8, y: u8) -> u8 {
- (x / 3) + (y / 3) * 3
- }
- #[cfg(test)]
- mod tests {
- // use crate::sudoku::*;
- use crate::group::*;
- // use crate::sudoku::group::*;
- // use crate::Group;
- // use group::*;
- // use crate::{for_cell, for_column, for_row};
- #[test]
- fn check_columns() {
- let mut g = Group::new();
- for i in 0..9 {
- println!("Index={}", i);
- g.for_column(i, 1);
- let new_g = for_column(i);
- assert_eq!(g, *new_g);
- }
- }
- #[test]
- fn check_rows() {
- let mut g = Group::new();
- for i in 0..9 {
- println!("Index={}", i);
- g.for_row(1, i);
- let new_g = for_row(i);
- assert_eq!(g, *new_g);
- }
- }
- #[test]
- fn check_cells() {
- let mut g = Group::new();
- for i in 0..9 {
- println!("Index={}", i);
- g.for_block((i % 3) * 3, (i / 3) * 3);
- let new_g = for_cell(i);
- assert_eq!(g, *new_g);
- }
- }
- }
- impl Group {
- pub fn new() -> Self {
- Group([0; WIDTH as usize])
- }
- pub fn for_column(&mut self, x: u8, _y: u8) {
- for y in 0..WIDTH {
- self.0[y as usize] = pos(x, y);
- }
- }
- pub fn for_row(&mut self, _x: u8, y: u8) {
- for x in 0..WIDTH {
- self.0[x as usize] = pos(x, y);
- }
- }
- pub 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..WIDTH {
- let ix = i % 3;
- let iy = i / 3;
- // println!("i = {}, sb.x = {} sb.y = {}, ix = {} iy = {}", i, sb_x, sb_y, ix, iy);
- self.0[i as usize] = pos(sb_x + ix, sb_y + iy);
- }
- }
- pub fn for_iter(&mut self, i: u8) {
- let sb_x = (i % 3) * 3;
- let sb_y = (i / 3) * 3;
- self.for_block(sb_x, sb_y);
- }
- pub fn display(&self) {
- for i in 0..WIDTH {
- let v = self.0[i as usize];
- print!("{} [{},{}] ", v, xy(v).0, xy(v).1);
- }
- println!("");
- }
- }
|