add code
This commit is contained in:
parent
db3bb87e9e
commit
cf1f4cfdcd
1 changed files with 169 additions and 0 deletions
169
src/main.rs
Normal file
169
src/main.rs
Normal file
|
@ -0,0 +1,169 @@
|
|||
struct Board([u8; 9 * 9]);
|
||||
struct SuperBoard([bool; 9 * 9 * 9]);
|
||||
|
||||
impl std::fmt::Display for Board {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for i in 0..9 * 9 {
|
||||
if i % 9 > 0 {
|
||||
if i % 3 == 0 {
|
||||
write!(f, "|")?;
|
||||
} else {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
} else if i > 0 && i % (9 * 3) == 0 {
|
||||
writeln!(f, "-----+-----+-----")?;
|
||||
}
|
||||
match self.0[i] {
|
||||
0 => {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
n => {
|
||||
write!(f, "{n}")?;
|
||||
}
|
||||
}
|
||||
if i % 9 == 8 {
|
||||
writeln!(f)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SuperBoard {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for j in 0..9 * 9 * 9 {
|
||||
let col = j / 3 % 9;
|
||||
let row = j / (9 * 9);
|
||||
let n = j / 9 / 3 % 3 * 3 + j % 3;
|
||||
|
||||
if j == 0 {
|
||||
// start of grid
|
||||
} else if j % 243 == 0 {
|
||||
writeln!(f, "-----------+-----------+-----------")?;
|
||||
} else if j % 81 == 0 {
|
||||
writeln!(f, "...........|...........|...........")?;
|
||||
} else if j % 27 == 0 {
|
||||
// start of line
|
||||
} else if j % 9 == 0 {
|
||||
write!(f, "|")?;
|
||||
} else if j % 3 == 0 {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
|
||||
let offset = n + (col * 9) + (row * 9 * 9);
|
||||
if self.0[offset] {
|
||||
write!(f, "{}", n + 1)?;
|
||||
} else {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
|
||||
if j % 27 == 26 {
|
||||
// end of line
|
||||
writeln!(f)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Board> for SuperBoard {
|
||||
fn from(board: &Board) -> SuperBoard {
|
||||
let mut super_board = [false; 9 * 9 * 9];
|
||||
|
||||
for (i, &cell) in board.0.iter().enumerate() {
|
||||
let super_i = i * 9;
|
||||
match cell {
|
||||
0 => {
|
||||
for i in 0..9 {
|
||||
super_board[super_i + i] = true;
|
||||
}
|
||||
}
|
||||
n => {
|
||||
super_board[super_i + n as usize - 1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SuperBoard(super_board)
|
||||
}
|
||||
}
|
||||
|
||||
impl Board {
|
||||
fn constrain(&mut self) -> Result<SuperBoard, ()> {
|
||||
let mut collapsed = self
|
||||
.0
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, &x)| x != 0)
|
||||
.map(|(i, _)| i)
|
||||
.collect::<Vec<_>>();
|
||||
let mut super_board = SuperBoard::from(&*self);
|
||||
|
||||
while let Some(i) = collapsed.pop() {
|
||||
let value = self.0[i];
|
||||
assert!(value > 0);
|
||||
let offset = (value - 1) as usize;
|
||||
|
||||
// column
|
||||
let col_start = i % 9;
|
||||
let row_start = i - col_start;
|
||||
let box_start = i / 27 * 27 + i % 9 / 3 * 3;
|
||||
let to_constrain = (col_start..81)
|
||||
.step_by(9)
|
||||
.chain((row_start..81).take(9))
|
||||
.chain((box_start..81).step_by(9).take(3).flat_map(|x| x..x + 3))
|
||||
.collect::<std::collections::HashSet<_>>();
|
||||
|
||||
for j in to_constrain.into_iter() {
|
||||
if i == j {
|
||||
continue;
|
||||
}
|
||||
|
||||
// safe to unwrap because none of the above can ever go outside the predefined bounds
|
||||
let x = &mut super_board.0[j * 9 + offset];
|
||||
if *x {
|
||||
*x = false;
|
||||
|
||||
let cell = &super_board.0[(j * 9)..(j * 9 + 9)];
|
||||
match cell.iter().filter(|&&x| x).count() {
|
||||
0 => return Err(()),
|
||||
1 => {
|
||||
self.0[j] = cell
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, &x)| x)
|
||||
.map(|(i, _)| i + 1)
|
||||
.unwrap() as u8;
|
||||
if !collapsed.contains(&j) {
|
||||
collapsed.push(j);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(super_board)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut board = Board([
|
||||
0, 6, 0, /**/ 0, 0, 1, /**/ 0, 0, 3,
|
||||
8, 0, 0, /**/ 0, 0, 0, /**/ 0, 1, 9,
|
||||
5, 0, 2, /**/ 0, 7, 0, /**/ 8, 4, 0,
|
||||
/**********************************/
|
||||
4, 0, 6, /**/ 9, 0, 2, /**/ 3, 0, 5,
|
||||
0, 0, 0, /**/ 8, 0, 7, /**/ 0, 0, 0,
|
||||
1, 0, 7, /**/ 5, 0, 3, /**/ 4, 0, 8,
|
||||
/**********************************/
|
||||
0, 4, 1, /**/ 0, 9, 0, /**/ 5, 0, 2,
|
||||
9, 2, 0, /**/ 0, 0, 0, /**/ 0, 0, 7,
|
||||
6, 0, 0, /**/ 2, 0, 0, /**/ 0, 9, 0,
|
||||
]);
|
||||
board.constrain().unwrap();
|
||||
println!("{}", board);
|
||||
}
|
Loading…
Reference in a new issue