You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.4 KiB
135 lines
3.4 KiB
|
|
use std::collections::HashSet;
|
|
|
|
#[derive(Clone)]
|
|
pub struct Playground {
|
|
arr: [[u8; 9]; 9]
|
|
}
|
|
|
|
impl Playground {
|
|
|
|
pub fn init(&mut self, data: String) {
|
|
let mut idx = 0;
|
|
for c in data.chars() {
|
|
idx = match c {
|
|
'1'..='9' => {
|
|
let value = c.to_digit(10).unwrap() as u8;
|
|
self.arr[idx / 9][idx % 9] = value;
|
|
idx + 1
|
|
},
|
|
'0' =>idx + 1,
|
|
_ => idx,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn new() -> Playground {
|
|
return Playground { arr: [[0; 9]; 9] };
|
|
}
|
|
|
|
pub fn from(s: &str) -> Playground {
|
|
let mut p = Playground::new();
|
|
p.init(String::from(s));
|
|
p
|
|
}
|
|
|
|
pub fn print(&self) {
|
|
println!("-------------------------------------");
|
|
for y in 0..9 {
|
|
print!("|");
|
|
for x in 0..9 {
|
|
let value = self.get_value(x, y);
|
|
if value.is_some() {
|
|
print!(" {} |", value.unwrap());
|
|
} else {
|
|
print!(" |");
|
|
}
|
|
}
|
|
println!();
|
|
|
|
println!("-------------------------------------");
|
|
}
|
|
}
|
|
|
|
pub fn get_value(&self, x: usize, y: usize) -> Option<u8> {
|
|
match self.arr[y][x] {
|
|
1..=9 => Some(self.arr[y][x]),
|
|
_ => None
|
|
}
|
|
}
|
|
|
|
pub fn set_value(&mut self, x: usize, y: usize, value : u8) {
|
|
self.arr[y][x] = value;
|
|
}
|
|
|
|
pub fn is_solved(&self) -> bool {
|
|
return self.arr.iter()
|
|
.flat_map(|row| row.iter())
|
|
.all(|value| *value != 0u8);
|
|
}
|
|
|
|
/** Checks if the playground has failures (not neccesary solved) */
|
|
pub fn is_valid(&self) -> bool {
|
|
self.rows_valid() && self.columns_valid() && self.sections_valid()
|
|
}
|
|
|
|
fn rows_valid(&self) -> bool {
|
|
let mut rows_set : HashSet<u8> = HashSet::with_capacity(9);
|
|
|
|
for x in 0..9 {
|
|
rows_set.clear();
|
|
|
|
for y in 0..9 {
|
|
if !rows_set.insert(self.arr[y][x]) {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
true
|
|
}
|
|
|
|
fn columns_valid(&self) -> bool {
|
|
let mut cols_set : HashSet<u8> = HashSet::with_capacity(9);
|
|
|
|
for y in 0..9 {
|
|
cols_set.clear();
|
|
|
|
for x in 0..9 {
|
|
if !cols_set.insert(self.arr[y][x]) {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
true
|
|
}
|
|
|
|
fn sections_valid(&self) -> bool {
|
|
let mut sects_set : HashSet<u8> = HashSet::with_capacity(9);
|
|
|
|
for s in 0..9 {
|
|
sects_set.clear();
|
|
let ref_point = ((s * 3) % 9, s / 3 * 3);
|
|
|
|
for i in 0..9 {
|
|
let (ref_x,ref_y) = ref_point;
|
|
if !sects_set.insert(self.arr[ref_y + (i/3)][ref_x + (i%3)]) {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
true
|
|
}
|
|
|
|
pub fn contains(&self, other : &Playground) -> bool {
|
|
for x in 0..9 {
|
|
for y in 0..9 {
|
|
if other.arr[y][x] != 0 && self.arr[y][x] != other.arr[y][x] {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
true
|
|
}
|
|
|
|
}
|