Solve Day 4: Printing Department

This commit is contained in:
Russell Champoux committed 2025-12-05 09:25:38 -05:00
1 parent d650dce61b
commit 52c3f31f54
3 files changed
+116 -1

No files matched your search

+2 -1
View File
@@ -14,8 +14,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 1](./src/bin/01.rs) | `102.5µs` | `123.5µs` | | [Day 1](./src/bin/01.rs) | `102.5µs` | `123.5µs` |
| [Day 2](./src/bin/02.rs) | `45.0ms` | `69.6ms` | | [Day 2](./src/bin/02.rs) | `45.0ms` | `69.6ms` |
| [Day 3](./src/bin/03.rs) | `85.1µs` | `121.6µs` | | [Day 3](./src/bin/03.rs) | `85.1µs` | `121.6µs` |
| [Day 4](./src/bin/04.rs) | `260.1µs` | `4.0ms` |
**Total: 115.03ms** **Total: 119.29ms**
<!--- benchmarking table ---> <!--- benchmarking table --->
--- ---
+11
View File
@@ -0,0 +1,11 @@
..@@.@@@@.
@@@.@.@.@@
@@@@@.@.@@
@.@@@@..@.
@@.@@@@.@@
.@@@@@@@.@
.@.@.@.@@@
@.@@@.@@@@
.@@@@@@@@.
@.@.@@@.@.
+103
View File
@@ -0,0 +1,103 @@
advent_of_code::solution!(4);
/// Count adjacent paper rolls (8 directions) for a given position
fn count_neighbors(grid: &[Vec<char>], row: usize, col: usize) -> usize {
let rows = grid.len() as i32;
let cols = grid[0].len() as i32;
let mut count = 0;
for dr in -1..=1 {
for dc in -1..=1 {
if dr == 0 && dc == 0 {
continue;
}
let nr = row as i32 + dr;
let nc = col as i32 + dc;
if nr >= 0 && nr < rows && nc >= 0 && nc < cols {
if grid[nr as usize][nc as usize] == '@' {
count += 1;
}
}
}
}
count
}
pub fn part_one(input: &str) -> Option<u64> {
let grid: Vec<Vec<char>> = input
.lines()
.filter(|line| !line.trim().is_empty())
.map(|line| line.chars().collect())
.collect();
let mut accessible = 0u64;
for (row, line) in grid.iter().enumerate() {
for (col, &ch) in line.iter().enumerate() {
// Only check paper rolls
if ch == '@' {
// Accessible if fewer than 4 neighbors
if count_neighbors(&grid, row, col) < 4 {
accessible += 1;
}
}
}
}
Some(accessible)
}
pub fn part_two(input: &str) -> Option<u64> {
let mut grid: Vec<Vec<char>> = input
.lines()
.filter(|line| !line.trim().is_empty())
.map(|line| line.chars().collect())
.collect();
let mut total_removed = 0u64;
loop {
// Find all accessible rolls (fewer than 4 neighbors)
let mut to_remove: Vec<(usize, usize)> = Vec::new();
for (row, line) in grid.iter().enumerate() {
for (col, &ch) in line.iter().enumerate() {
if ch == '@' && count_neighbors(&grid, row, col) < 4 {
to_remove.push((row, col));
}
}
}
// If no rolls are accessible, we're done
if to_remove.is_empty() {
break;
}
// Remove all accessible rolls
for (row, col) in &to_remove {
grid[*row][*col] = '.';
}
total_removed += to_remove.len() as u64;
}
Some(total_removed)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(13));
}
#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(43));
}
}