Basic knowledge of self and regions
This commit is contained in:
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in library 'rustdoku'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--lib",
|
||||||
|
"--package=rustdoku"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "rustdoku",
|
||||||
|
"kind": "lib"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Generated
+9
@@ -2,6 +2,15 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "assertables"
|
||||||
|
version = "8.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "857057651cdf1fe4bc1e8308493c752db559df0330f23b45f532f6b24c2b443d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustdoku"
|
name = "rustdoku"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"assertables",
|
||||||
|
]
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
assertables = "8.18.0"
|
||||||
|
|||||||
+132
@@ -0,0 +1,132 @@
|
|||||||
|
use crate::cell::{Cell, CellValue};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
pub struct Board {
|
||||||
|
cells: Vec<Vec<Cell>>,
|
||||||
|
regions: Vec<Region>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Board {
|
||||||
|
pub fn new() -> Board {
|
||||||
|
let mut rows = Vec::with_capacity(9);
|
||||||
|
for _ in 0..9 {
|
||||||
|
let mut col = Vec::with_capacity(9);
|
||||||
|
for _ in 0..9 {
|
||||||
|
col.push(Cell::default());
|
||||||
|
}
|
||||||
|
rows.push(col);
|
||||||
|
}
|
||||||
|
let mut regions = Vec::with_capacity(9);
|
||||||
|
for x in 0..3 {
|
||||||
|
for y in 0..3 {
|
||||||
|
regions.push(Region::new(&Point(x, y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let board = Board {
|
||||||
|
cells: rows,
|
||||||
|
regions
|
||||||
|
};
|
||||||
|
board
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self, point: &Point) -> Option<CellValue> {
|
||||||
|
self.cells[point.0][point.1].value()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_value(&mut self, point: &Point, value: CellValue) {
|
||||||
|
self.cells[point.0][point.1].set_value(value);
|
||||||
|
self.update_row(point.0, value);
|
||||||
|
self.update_column(point.1, value);
|
||||||
|
self.update_region(point, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_row(&mut self, x: usize, value: CellValue) {
|
||||||
|
for i in self.cells[x].iter_mut() {
|
||||||
|
i.remove_candidate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_column(&mut self, y: usize, value: CellValue) {
|
||||||
|
for i in self.cells.iter_mut() {
|
||||||
|
(*i)[y].remove_candidate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_region(&mut self, point: &Point, value: CellValue) {
|
||||||
|
for i in self.regions.iter_mut() {
|
||||||
|
if i.includes(point) {
|
||||||
|
for pt in i.iter_mut() {
|
||||||
|
self.cells[pt.0][pt.1].remove_candidate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn candidates(&self, point: &Point) -> HashSet<CellValue> {
|
||||||
|
self.cells[point.0][point.1].candidates()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub struct Point(usize, usize);
|
||||||
|
|
||||||
|
pub struct Region {
|
||||||
|
points: Vec<Point>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Region {
|
||||||
|
pub fn new(start: &Point)-> Region {
|
||||||
|
let mut points = Vec::with_capacity(9);
|
||||||
|
for x in start.0..(start.0 + 3) {
|
||||||
|
for y in start.1..(start.1 + 3) {
|
||||||
|
points.push(Point(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Region {
|
||||||
|
points,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> std::slice::Iter<Point> {
|
||||||
|
self.points.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn includes(&self, point: &Point) -> bool {
|
||||||
|
self.points.contains(point)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_mut(&mut self) -> std::slice::IterMut<Point> {
|
||||||
|
self.points.iter_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use assertables::{assert_contains, assert_not_contains};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn has_none_values() {
|
||||||
|
let board = Board::new();
|
||||||
|
assert!(board.value(&Point(0, 0)).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn set_value_updates_cell() {
|
||||||
|
let mut board = Board::new();
|
||||||
|
board.set_value(&Point(0, 0), CellValue::One);
|
||||||
|
let val = board.value(&Point(0, 0)).unwrap();
|
||||||
|
assert_eq!(val, CellValue::One);
|
||||||
|
|
||||||
|
// Same column
|
||||||
|
assert_not_contains!(board.candidates(&Point(0, 1)), &CellValue::One);
|
||||||
|
// Same row
|
||||||
|
assert_not_contains!(board.candidates(&Point(1, 0)), &CellValue::One);
|
||||||
|
// Same sub-structure
|
||||||
|
assert_not_contains!(board.candidates(&Point(1, 1)), &CellValue::One);
|
||||||
|
|
||||||
|
// Different row
|
||||||
|
assert_contains!(board.candidates(&Point(8, 8)), &CellValue::One);
|
||||||
|
}
|
||||||
|
}
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Copy, Hash, Eq, PartialEq)]
|
||||||
|
pub enum CellValue {
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
Four,
|
||||||
|
Five,
|
||||||
|
Six,
|
||||||
|
Seven,
|
||||||
|
Eight,
|
||||||
|
Nine,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Cell {
|
||||||
|
value: Option<CellValue>,
|
||||||
|
candidates: HashSet<CellValue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cell {
|
||||||
|
pub fn value(&self) -> Option<CellValue> {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_value(&mut self, value: CellValue) {
|
||||||
|
self.value = Some(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn candidates(&self) -> HashSet<CellValue> {
|
||||||
|
self.candidates.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_candidate(&mut self, value: CellValue) {
|
||||||
|
self.candidates.remove(&value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Cell {
|
||||||
|
fn default() -> Cell {
|
||||||
|
let mut candidates = HashSet::new();
|
||||||
|
candidates.insert(CellValue::One);
|
||||||
|
candidates.insert(CellValue::Two);
|
||||||
|
candidates.insert(CellValue::Three);
|
||||||
|
candidates.insert(CellValue::Four);
|
||||||
|
candidates.insert(CellValue::Five);
|
||||||
|
candidates.insert(CellValue::Six);
|
||||||
|
candidates.insert(CellValue::Seven);
|
||||||
|
candidates.insert(CellValue::Eight);
|
||||||
|
candidates.insert(CellValue::Nine);
|
||||||
|
Cell {
|
||||||
|
value: None,
|
||||||
|
candidates,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use assertables::{assert_contains, assert_not_contains};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inits_empty() {
|
||||||
|
let cell = Cell::default();
|
||||||
|
assert!(cell.value().is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn has_all_candidates() {
|
||||||
|
let cell = Cell::default();
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::One);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Two);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Three);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Four);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Five);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Six);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Seven);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Eight);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Nine);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn removed_candidate_is_gone() {
|
||||||
|
let mut cell = Cell::default();
|
||||||
|
cell.remove_candidate(CellValue::One);
|
||||||
|
assert_not_contains!(cell.candidates(), &CellValue::One);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Two);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Three);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Four);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Five);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Six);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Seven);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Eight);
|
||||||
|
assert_contains!(cell.candidates(), &CellValue::Nine);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-62
@@ -1,62 +1,2 @@
|
|||||||
#[derive(Clone, Debug, Copy)]
|
pub mod cell;
|
||||||
pub enum CellValue {
|
pub mod board;
|
||||||
One,
|
|
||||||
Two,
|
|
||||||
Three,
|
|
||||||
Four,
|
|
||||||
Five,
|
|
||||||
Six,
|
|
||||||
Seven,
|
|
||||||
Eight,
|
|
||||||
Nine,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Cell {
|
|
||||||
value: Option<CellValue>,
|
|
||||||
candidates: Vec<CellValue>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Cell {
|
|
||||||
fn default() -> Cell {
|
|
||||||
Cell {
|
|
||||||
value: None,
|
|
||||||
candidates: vec![
|
|
||||||
CellValue::One,
|
|
||||||
CellValue::Two,
|
|
||||||
CellValue::Three,
|
|
||||||
CellValue::Four,
|
|
||||||
CellValue::Five,
|
|
||||||
CellValue::Six,
|
|
||||||
CellValue::Seven,
|
|
||||||
CellValue::Eight,
|
|
||||||
CellValue::Nine,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Board {
|
|
||||||
cells: [[Cell; 9]; 9],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Board {
|
|
||||||
fn value(self, x: usize, y: usize) -> Option<CellValue> {
|
|
||||||
self.cells[x][y].value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(left: u64, right: u64) -> u64 {
|
|
||||||
left + right
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user