From 6acb491b45e742427dd866529f88e2eef948c229 Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Wed, 3 Dec 2025 22:07:36 -0800 Subject: [PATCH] grid improvements --- .aoc_tiles/tiles/2025/04.png | Bin 6281 -> 7308 bytes README.md | 2 +- utils/grid/lib.rs | 46 +++++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/.aoc_tiles/tiles/2025/04.png b/.aoc_tiles/tiles/2025/04.png index 2b574ecec7196188c4510c8d48263097d4fdbdfa..4a614fa452dd8991afc04c258572c5266f8c3b06 100644 GIT binary patch literal 7308 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 literal 6281 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

- 2025 - 7 ⭐ - Rust + 2025 - 8 ⭐ - Rust

diff --git a/utils/grid/lib.rs b/utils/grid/lib.rs index 2b0b6e3..38d395a 100644 --- a/utils/grid/lib.rs +++ b/utils/grid/lib.rs @@ -149,7 +149,34 @@ impl<'a, T: Clone + Eq + PartialEq + Debug> Iterator for CoordIter<'a, T> { type Item = Coord2d; fn next(&mut self) -> Option { if self.pos < self.grid.data.len() { - self.grid.coord(self.pos as i64).into() + self.pos += 1; + self.grid.coord(self.pos as i64 - 1).into() + } else { + None + } + } +} + +#[derive(Debug)] +pub struct ItemIter<'a, T> { + pos: usize, + grid: &'a Grid, +} + +pub struct Item<'a, T> { + pub pos: Coord2d, + pub value: &'a T, +} + +impl<'a, T: Clone + Eq + PartialEq + Debug> Iterator for ItemIter<'a, T> { + type Item = Item<'a, T>; + fn next(&mut self) -> Option { + if self.pos < self.grid.data.len() { + self.pos += 1; + Some(Item { + pos: self.grid.coord(self.pos as i64 - 1).unwrap(), + value: &self.grid.data[self.pos - 1], + }) } else { None } @@ -226,9 +253,12 @@ impl Grid { }) } } - // pub fn coord_iter(&self) -> CoordIter<_> { - // CoordIter { pos: 0, grid: self } - // } + pub fn coord_iter<'a>(&'a self) -> CoordIter<'a, T> { + CoordIter { pos: 0, grid: self } + } + pub fn item_iter<'a>(&'a self) -> ItemIter<'a, T> { + ItemIter { pos: 0, grid: self } + } pub fn is_valid(&self, c: &C) -> bool { if c.x() < 0 || c.x() >= self.width { return false; @@ -292,7 +322,7 @@ impl Grid { } } - pub fn row_iter(&self, y: i64) -> Option> { + pub fn row_iter<'a>(&'a self, y: i64) -> Option> { if (y as usize) < self.height() { Some(GridRowIter::new(self, y)) } else { @@ -308,7 +338,7 @@ impl Grid { } } - pub fn col_iter(&self, x: i64) -> Option> { + pub fn col_iter<'a>(&'a self, x: i64) -> Option> { if (x as usize) < self.width() { Some(GridColIter::new(self, x)) } else { @@ -316,13 +346,13 @@ impl Grid { } } - pub fn find(&self, haystack: &T) -> Option { + pub fn find(&self, needle: &T) -> Option { self.coord( self.data .iter() .enumerate() .find_map(|(pos, val)| { - if val == haystack { + if val == needle { Some(pos as i64) } else { None