day4: add removal queue implementation for part2

This commit is contained in:
2025-12-04 17:29:12 -08:00
parent fa7f62cacf
commit d49157dd79

View File

@@ -1,12 +1,13 @@
use aoc_runner_derive::{aoc, aoc_generator};
use grid::Grid;
use itertools::Itertools;
#[aoc_generator(day4)]
fn parse(input: &str) -> Grid<u8> {
input.parse().unwrap()
}
#[aoc(day4, part1)]
#[aoc(day4, part1, Brute)]
fn part1(input: &Grid<u8>) -> u64 {
(0..input.height() * input.width())
.filter(|i| *input.get(&input.coord(*i as i64).unwrap()).unwrap() == b'@')
@@ -14,7 +15,8 @@ fn part1(input: &Grid<u8>) -> u64 {
.filter(|n| *n < 4)
.count() as u64
}
#[aoc(day4, part2)]
#[aoc(day4, part2, Brute)]
fn part2(input: &Grid<u8>) -> u64 {
let mut grid = input.clone();
let mut removed = 0;
@@ -38,6 +40,30 @@ fn part2(input: &Grid<u8>) -> u64 {
}
}
#[aoc(day4, part2, RollList)]
fn part2_list(input: &Grid<u8>) -> u64 {
let mut grid = input.clone();
let mut to_check = grid.find_all(&b'@').collect_vec();
let mut removed = 0;
while let Some(roll) = to_check.pop() {
if grid.get(&roll).is_none_or(|c| *c == b'.') {
continue;
}
let adjacent_rolls = grid
.adjacent_iter(&roll)
.filter_map(|i| if *i.value == b'@' { Some(i.pos) } else { None })
.collect_vec();
if adjacent_rolls.len() < 4 {
grid.set(&roll, b'.');
removed += 1;
to_check.extend_from_slice(&adjacent_rolls);
}
}
removed
}
#[cfg(test)]
mod tests {
use super::*;
@@ -62,4 +88,9 @@ mod tests {
fn part2_example() {
assert_eq!(part2(&parse(EXAMPLE)), 43);
}
#[test]
fn part2_list_example() {
assert_eq!(part2_list(&parse(EXAMPLE)), 43);
}
}