Brought code up to point where it can run and fill in and print a grid.

This commit is contained in:
Joel Therrien 2020-09-06 12:29:42 -07:00
parent 3d038ab84e
commit 79b20a5155

View file

@ -1,4 +1,12 @@
use std::borrow::BorrowMut; use std::rc::Rc;
use std::cell::RefCell;
struct Grid {
rows: Vec<Vec<Rc<RefCell<CellValue>>>>, // Read from top to bottom
columns: Vec<Vec<Rc<RefCell<CellValue>>>>,
sections: Vec<Vec<Rc<RefCell<CellValue>>>>
}
enum CellValue { enum CellValue {
FIXED(u8), FIXED(u8),
@ -6,33 +14,28 @@ enum CellValue {
UNKNOWN(Vec<u8>) UNKNOWN(Vec<u8>)
} }
struct Cell(CellValue); impl Grid {
fn get(&self, r: usize, c: usize) -> Result<Rc<RefCell<CellValue>>, &str> {
struct Grid<'a> { if (r > 9) | (c > 9) {
rows: Vec<[&'a mut Cell; 9]>, // Read from top to bottom return Err("Row or column indices are out of bounds");
columns: Vec<[&'a Cell; 9]>, // Left to right
sections: Vec<[&'a Cell; 9]> // left to right, top to bottom
} }
impl<'a> Grid<'a> { let row = match self.rows.get(r) {
fn get(&self, r: usize, c: usize) -> Option<&Cell> { Some(x) => x,
let row = self.rows.get(r)?; None => {return Err("Row index is out of bounds")}
let cell = &row[c]; };
return Some(&cell); let cell = match row.get(c) {
} Some(x) => x,
None => {return Err("Column index is out of bounds")}
fn get_mut(&'a mut self, r: usize, c: usize) -> Option<&'a mut Cell> { };
let row : &'a mut [&'a mut Cell; 9] = self.rows.get_mut(r)?;
let cell : &'a mut Cell = row[c].borrow_mut();
return Some(cell);
return Ok(Rc::clone(cell));
} }
fn print(&self) { fn print(&self) {
for r in 0..9 { for r in 0..9 {
if (r & 3 == 0) && (r > 0) { if (r % 3 == 0) && (r > 0) {
println!("---+---+---"); println!("---+---+---");
} }
@ -41,65 +44,55 @@ impl<'a> Grid<'a> {
print!("|"); print!("|");
} }
let value = &self.get(r, c).unwrap().0; let value = self.get(r, c).unwrap_or_else(|err| panic!());
match value { match *value.borrow() {
CellValue::FIXED(x) => print!("{}", x), CellValue::FIXED(x) => print!("{}", x),
_ => print!(" ") _ => print!(" ")
}; };
} }
print!("\n"); print!("\n");
} }
} }
}
fn main() {
println!("Hello, world!");
let grid = retrieve_grid();
grid.print();
}
fn empty_grid<'a>() -> Grid<'a> {
let mut placeholder_cell : Cell = Cell(CellValue::FIXED(0));
fn new() -> Grid {
// Rows first; we need to create cells for all of them // Rows first; we need to create cells for all of them
let mut rows : Vec<[&'a mut Cell; 9]> = Vec::new(); let mut rows: Vec<Vec<Rc<RefCell<CellValue>>>> = Vec::new();
for _r in 0..9 { for _r in 0..9 {
let mut new_row : [&'a mut Cell; 9] = [&mut placeholder_cell; 9]; let mut new_row: Vec<Rc<RefCell<CellValue>>> = Vec::new();
for i in 0..9{
new_row[i] = &mut initial_empty_cell();
}
for _i in 0..9 {
let empty_cell = initial_empty_cell();
new_row.push(Rc::new(empty_cell));
}
rows.push(new_row); rows.push(new_row);
} }
// Columns next; now we have to retrieve the cells from the different rows // Columns next; now we have to retrieve the cells from the different rows
let mut columns : Vec<[&'a Cell; 9]> = Vec::new(); let mut columns : Vec<Vec<Rc<RefCell<CellValue>>>> = Vec::new();
for c in 0..9 { for c in 0..9 {
let mut new_column : [&'a Cell; 9] = [&placeholder_cell; 9]; let mut new_column : Vec<Rc<RefCell<CellValue>>> = Vec::new();
for r in 0..9{ for r in 0..9{
new_column[r] = rows.get(r).unwrap()[c]; // TODO - improve performance by using get_unchecked new_column.push(Rc::clone(&rows.get(r).unwrap()[c]));
} }
columns.push(new_column); columns.push(new_column);
} }
// Sections next; now we have to retrieve the cells from different rows and columns // Sections next; now we have to retrieve the cells from different rows and columns
// We read sections from left to right, top to bottom // We read sections from left to right, top to bottom
let mut sections : Vec<[&'a Cell; 9]> = Vec::new(); let mut sections : Vec<Vec<Rc<RefCell<CellValue>>>> = Vec::new();
for r in 0..3 { for r in 0..3 {
for c in 0..3 { for c in 0..3 {
let mut new_section : [&'a Cell; 9] = [&placeholder_cell; 9]; let mut new_section : Vec<Rc<RefCell<CellValue>>> = Vec::new();
for internal_r in 0..3 { for internal_r in 0..3 {
let global_r = 3*r + internal_r; let global_r = 3*r + internal_r;
for internal_c in 0..3 { for internal_c in 0..3 {
let global_c = 3*c + internal_c; let global_c = 3*c + internal_c;
let index = 3*internal_c + internal_r;
new_section[index] = rows.get(global_r).unwrap()[global_c]; new_section.push(Rc::clone(&rows.get(global_r).unwrap()[global_c]));
} }
} }
@ -110,16 +103,65 @@ fn empty_grid<'a>() -> Grid<'a> {
return Grid { rows, columns, sections }; return Grid { rows, columns, sections };
} }
fn initial_empty_cell() -> Cell {
return Cell(CellValue::UNKNOWN(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]));
} }
fn initial_empty_cell() -> RefCell<CellValue> {
return RefCell::new(CellValue::UNKNOWN(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]));
}
fn main() {
println!("Hello, world!");
let grid = retrieve_grid();
grid.print();
}
/** /**
For now this is a stub with a pre-programmed grid; later I'll add functionality to read a CSV file For now this is a stub with a pre-programmed grid; later I'll add functionality to read a CSV file
*/ */
fn retrieve_grid<'a>() -> Grid<'a> { fn retrieve_grid() -> Grid {
let mut grid = empty_grid(); let grid = Grid::new();
grid.get(0, 4).unwrap().replace(CellValue::FIXED(8));
grid.get(0, 5).unwrap().replace(CellValue::FIXED(5));
grid.get(0, 6).unwrap().replace(CellValue::FIXED(6));
grid.get(2, 3).unwrap().replace(CellValue::FIXED(9));
grid.get(2, 4).unwrap().replace(CellValue::FIXED(4));
grid.get(2, 5).unwrap().replace(CellValue::FIXED(3));
grid.get(2, 6).unwrap().replace(CellValue::FIXED(5));
grid.get(2, 7).unwrap().replace(CellValue::FIXED(7));
grid.get(3, 0).unwrap().replace(CellValue::FIXED(8));
grid.get(3, 2).unwrap().replace(CellValue::FIXED(2));
grid.get(3, 3).unwrap().replace(CellValue::FIXED(6));
grid.get(3, 4).unwrap().replace(CellValue::FIXED(7));
grid.get(3, 5).unwrap().replace(CellValue::FIXED(4));
grid.get(3, 6).unwrap().replace(CellValue::FIXED(9));
grid.get(4, 4).unwrap().replace(CellValue::FIXED(9));
grid.get(4, 8).unwrap().replace(CellValue::FIXED(5));
grid.get(5, 1).unwrap().replace(CellValue::FIXED(6));
grid.get(5, 6).unwrap().replace(CellValue::FIXED(2));
grid.get(6, 1).unwrap().replace(CellValue::FIXED(8));
grid.get(6, 8).unwrap().replace(CellValue::FIXED(2));
grid.get(7, 3).unwrap().replace(CellValue::FIXED(7));
grid.get(7, 5).unwrap().replace(CellValue::FIXED(6));
grid.get(7, 7).unwrap().replace(CellValue::FIXED(5));
grid.get(7, 8).unwrap().replace(CellValue::FIXED(4));
grid.get(8, 2).unwrap().replace(CellValue::FIXED(7));
grid.get(8, 3).unwrap().replace(CellValue::FIXED(4));
/*
grid.get_mut(0, 4).unwrap().0 = CellValue::FIXED(8); grid.get_mut(0, 4).unwrap().0 = CellValue::FIXED(8);
grid.get_mut(0, 5).unwrap().0 = CellValue::FIXED(5); grid.get_mut(0, 5).unwrap().0 = CellValue::FIXED(5);
@ -155,6 +197,8 @@ fn retrieve_grid<'a>() -> Grid<'a> {
grid.get_mut(8, 2).unwrap().0 = CellValue::FIXED(7); grid.get_mut(8, 2).unwrap().0 = CellValue::FIXED(7);
grid.get_mut(8, 3).unwrap().0 = CellValue::FIXED(4); grid.get_mut(8, 3).unwrap().0 = CellValue::FIXED(4);
*/
return grid; return grid;
} }