From d0c14d004f9b64e7fe093987852d4904fa015352 Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Fri, 12 Dec 2025 00:15:11 -0800 Subject: [PATCH] grid: add rotated/mirrored --- .aoc_tiles/tiles/2025/12.png | Bin 0 -> 5442 bytes README.md | 5 ++- utils/grid/lib.rs | 80 ++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 .aoc_tiles/tiles/2025/12.png diff --git a/.aoc_tiles/tiles/2025/12.png b/.aoc_tiles/tiles/2025/12.png new file mode 100644 index 0000000000000000000000000000000000000000..efc17e565d7926da9e9e7924fce18df3af1bed31 GIT binary patch literal 5442 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 literal 0 HcmV?d00001 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();