diff --git a/utils/src/grid.rs b/utils/src/grid.rs --- a/utils/src/grid.rs +++ b/utils/src/grid.rs @@ -156,6 +156,13 @@ .get(pos.y as usize) .and_then(|row| row.get(pos.x as usize)) } + /// Obtain a mutable reference to a tile in the grid + pub fn get_mut<'a>(&'a mut self, pos: Position) -> Option<&'a mut T> { + self.data + .get_mut(pos.y as usize) + .and_then(|row| row.get_mut(pos.x as usize)) + } + /// Get a value from the grid at the given position, /// panicking if the position is out of bounds. /// diff --git a/years/2025/src/day_2.rs b/years/2025/src/day_2.rs --- a/years/2025/src/day_2.rs +++ b/years/2025/src/day_2.rs @@ -28,7 +28,7 @@ .into_iter() .flat_map(|r| { r.into_iter().filter(|x| { let digs = num_digits(*x); - (2..=digs).into_iter().filter(|n| digs % n == 0).any(|n| { + (2..=digs).filter(|n| digs.is_multiple_of(*n)).any(|n| { let mut parts = Vec::with_capacity(n); let mut current = *x; let split_at = digs / n; @@ -40,7 +40,7 @@ } parts .first() .copied() - .map_or(false, |first| parts.into_iter().all(|x| x == first)) + .is_some_and(|first| parts.into_iter().all(|x| x == first)) }) }) }) diff --git a/years/2025/src/day_4.rs b/years/2025/src/day_4.rs --- a/years/2025/src/day_4.rs +++ b/years/2025/src/day_4.rs @@ -1,17 +1,65 @@ - use advent_core::{Day, day_stuff, ex_for_day}; +use utils::{dir::ALL_8, tiles}; pub struct Day4; +tiles!(Tile, [ + '@' => Paper, + '.' => Empty +]); + +type Grid = utils::grid::Grid; + impl Day for Day4 { + day_stuff!(4, "13", "43", Grid); - day_stuff!(4, "", ""); + fn part_1(input: Self::Input) -> Option { + let ans = input + .iter() + .filter(|(_, t)| **t == Tile::Paper) + .filter(|(pos, _)| { + input + .relatives(*pos, &ALL_8) + .filter(|(_, _, t)| **t == Tile::Paper) + .count() + < 4 + }) + .count(); - fn part_1(_input: Self::Input) -> Option { - None + Some(ans.to_string()) } - fn part_2(_input: Self::Input) -> Option { - None + fn part_2(mut input: Self::Input) -> Option { + let mut i = 0; + + loop { + let next = input + .iter() + .filter(|(_, t)| **t == Tile::Paper) + .filter(|(pos, _)| { + input + .relatives(*pos, &ALL_8) + .filter(|(_, _, t)| **t == Tile::Paper) + .count() + < 4 + }) + .map(|(p, _)| p) + .collect::>(); + + if next.is_empty() { + break; + } else { + i += next.len(); + for pos in next { + *(input.get_mut(pos).unwrap()) = Tile::Empty; + } + } + } + + Some(i.to_string()) + } + + fn parse_input(input: &str) -> Self::Input { + Grid::parse(input) } } diff --git a/years/2025/src/examples/day_4/1.txt b/years/2025/src/examples/day_4/1.txt --- a/years/2025/src/examples/day_4/1.txt +++ b/years/2025/src/examples/day_4/1.txt @@ -0,0 +1,10 @@ +..@@.@@@@. +@@@.@.@.@@ +@@@@@.@.@@ +@.@@@@..@. +@@.@@@@.@@ +.@@@@@@@.@ +.@.@.@.@@@ +@.@@@.@@@@ +.@@@@@@@@. +@.@.@@@.@. diff --git a/years/2025/src/examples/day_4/2.txt b/years/2025/src/examples/day_4/2.txt --- a/years/2025/src/examples/day_4/2.txt +++ b/years/2025/src/examples/day_4/2.txt @@ -0,0 +1,10 @@ +..@@.@@@@. +@@@.@.@.@@ +@@@@@.@.@@ +@.@@@@..@. +@@.@@@@.@@ +.@@@@@@@.@ +.@.@.@.@@@ +@.@@@.@@@@ +.@@@@@@@@. +@.@.@@@.@.