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 { 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 = 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 = 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 = 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 } }