diff --git a/.aoc_tiles/tiles/2025/12.png b/.aoc_tiles/tiles/2025/12.png new file mode 100644 index 0000000..efc17e5 Binary files /dev/null and b/.aoc_tiles/tiles/2025/12.png differ diff --git a/README.md b/README.md index 923f7eb..e6d0a16 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- 2025 - 20 ⭐ - Rust + 2025 - 21 ⭐ - Rust

@@ -35,4 +35,7 @@ + + + diff --git a/utils/grid/lib.rs b/utils/grid/lib.rs index 6e60bc5..69205ad 100644 --- a/utils/grid/lib.rs +++ b/utils/grid/lib.rs @@ -22,6 +22,11 @@ pub const ADJACENT_OFFSETS: [&(i64, i64); 8] = [ /// NESW pub const CARDINAL_OFFSETS: [&(i64, i64); 4] = [&(0, -1), &(-1, 0), &(1, 0), &(0, 1)]; +pub enum MirrorAxis { + X, + Y, +} + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] pub struct Coord2d { pub x: i64, @@ -281,7 +286,7 @@ impl<'a, T: Clone + Eq + PartialEq + Debug> Iterator for OffsetsIter<'a, T> { } } -#[derive(Clone, Eq, PartialEq, Debug)] +#[derive(Clone, Eq, PartialEq, Debug, Hash)] pub struct Grid { pub data: Vec, width: i64, @@ -486,6 +491,79 @@ impl Grid { } } + pub fn rotated(&self, mut rot: u8) -> Self { + rot %= 4; + match rot { + 0 => self.clone(), + 1 => { + let mut n = Grid::with_shape(self.height(), self.width(), self.data[0].clone()); // fill will be overwritten anyway + for y in 0..self.height() { + for x in 0..self.width() { + n.set( + &(self.height() - y - 1, x), + self.get(&(x as u64, y as u64)).unwrap().clone(), + ); + } + } + n + } + 2 => { + let mut n = Grid::with_shape(self.height(), self.width(), self.data[0].clone()); // fill will be overwritten anyway + for y in 0..self.height() { + for x in 0..self.width() { + n.set( + &(self.width() - x - 1, self.height() - y - 1), + self.get(&(x as u64, y as u64)).unwrap().clone(), + ); + } + } + n + } + 3 => { + let mut n = Grid::with_shape(self.height(), self.width(), self.data[0].clone()); // fill will be overwritten anyway + for y in 0..self.height() { + for x in 0..self.width() { + n.set( + &(self.height() - y - 1, self.width() - x - 1), + self.get(&(x as u64, y as u64)).unwrap().clone(), + ); + } + } + n + } + _ => unreachable!("invalid rotation"), + } + } + + pub fn mirrored(&self, axis: MirrorAxis) -> Self { + match axis { + MirrorAxis::X => { + let mut n = Grid::with_shape(self.height(), self.width(), self.data[0].clone()); // fill will be overwritten anyway + for y in 0..self.height() { + for x in 0..self.width() { + n.set( + &(self.width() - x - 1, y), + self.get(&(x as u64, y as u64)).unwrap().clone(), + ); + } + } + n + } + MirrorAxis::Y => { + let mut n = Grid::with_shape(self.height(), self.width(), self.data[0].clone()); // fill will be overwritten anyway + for y in 0..self.height() { + for x in 0..self.width() { + n.set( + &(x, &self.height() - y - 1), + self.get(&(x as u64, y as u64)).unwrap().clone(), + ); + } + } + n + } + } + } + // fn window_compare_impl(&self, needle: &[T]) -> Vec<(i64, i64)> { // if (self.width as usize) < needle.len() { // return Vec::new();