diff --git a/aoc-shared/Cargo.lock b/aoc-shared/Cargo.lock new file mode 100644 index 0000000..f517cd2 --- /dev/null +++ b/aoc-shared/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aoc-shared" +version = "0.1.0" diff --git a/aoc-shared/Cargo.toml b/aoc-shared/Cargo.toml new file mode 100644 index 0000000..ca58dcd --- /dev/null +++ b/aoc-shared/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "aoc-shared" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/aoc-shared/src/grid.rs b/aoc-shared/src/grid.rs new file mode 100644 index 0000000..7d2027e --- /dev/null +++ b/aoc-shared/src/grid.rs @@ -0,0 +1,108 @@ +/// Reusing part of day 8's solution for a virtual 2d grid + +#[derive(Debug)] +pub struct Grid { + width: usize, + pub vec: Vec, +} + +pub trait Grid2d { + fn new(width: usize) -> Self; + + fn len(&self) -> usize; + + fn num_cols(&self) -> usize; + + fn num_rows(&self) -> usize { + self.len() / self.num_cols() + } + + // Convert x,y coordinate into linear array index + fn xy_idx(&self, x: usize, y: usize) -> usize { + (y * self.num_cols()) + x + } + + /// Convert linear array index to x,y coordinate + fn idx_xy(&self, idx: usize) -> (usize, usize) { + (idx % self.num_cols(), idx / self.num_cols()) + } + + fn get(&self, idx: usize) -> Option<&T>; + + fn get_mut(&mut self, idx: usize) -> Option<&mut T>; + + fn get_row(&mut self, row_num: usize) -> &mut [T]; + + fn row_first_idx(&self, row: usize) -> usize { + let idx = row * self.num_cols(); + + if idx < self.len() { + idx + } else { + self.len() + } + } + + fn row_last_idx(&self, row: usize) -> usize { + if (row + 1) > self.num_rows() { + return self.len(); + } + + self.row_first_idx(row + 1) - 1 + } + + fn get_row_indexes(&self, row_num: usize) -> Vec { + (self.row_first_idx(row_num)..=self.row_last_idx(row_num)).collect() + } + + fn get_column_indexes(&self, col_num: usize) -> Vec { + let mut indexes = Vec::new(); + + if col_num >= self.num_cols() { + panic!( + "Asked for column {}, there are {} columns", + col_num, + self.num_cols() + ); + } + + for r in 0..self.num_rows() { + let idx = self.num_cols() * r + col_num; + indexes.push(idx); + } + + indexes + } +} + +impl Grid2d for Grid { + fn new(width: usize) -> Self { + Grid { + width, + vec: Vec::new(), + } + } + + fn len(&self) -> usize { + self.vec.len() + } + + fn num_cols(&self) -> usize { + self.width + } + + fn get(&self, idx: usize) -> Option<&T> { + self.vec.get(idx) + } + + fn get_mut(&mut self, idx: usize) -> Option<&mut T> { + self.vec.get_mut(idx) + } + + fn get_row(&mut self, row_num: usize) -> &mut [T] { + let start = self.row_first_idx(row_num); + let end = self.row_last_idx(row_num); + + &mut self.vec[start..=end] + } +} diff --git a/aoc-shared/src/lib.rs b/aoc-shared/src/lib.rs new file mode 100644 index 0000000..204404f --- /dev/null +++ b/aoc-shared/src/lib.rs @@ -0,0 +1,2 @@ +pub mod grid; +pub use grid::*;