Skip to main content

aoc/year2025/
day06.rs

1//! # Trash Compactor
2//!
3//! Processing the input from right to left means that we can use the operator on the bottom row
4//! to split blocks of numbers and don't need special-case handling for the end of the input.
5//! Blocks are the same height but can be different widths.
6//!
7//! Both parts are computed together. Each block is converted into a set of numbers twice,
8//! in rows from top to bottom and columns from left to right.
9//! Leading and trailing spaces are ignored.
10//!
11//! For performance, we avoid storing the numbers in an intermediate `vec` and just use the
12//! iterators directly.
13use crate::util::grid::*;
14use crate::util::parse::*;
15use crate::util::point::*;
16
17type Input = (u64, u64);
18
19pub fn parse(input: &str) -> Input {
20    let grid = Grid::parse(input);
21    let bottom = grid.height - 1;
22    let mut right = grid.width;
23    let mut part_one = 0;
24    let mut part_two = 0;
25
26    // Use operator on bottom row to delimit block boundaries.
27    for left in (0..grid.width).rev().filter(|&x| grid[Point::new(x, bottom)] != b' ') {
28        let rows = (0..bottom).map(|y| (left..right).fold(0, |num, x| acc(&grid, num, x, y)));
29        let cols = (left..right).map(|x| (0..bottom).fold(0, |num, y| acc(&grid, num, x, y)));
30
31        // Use iterators directly.
32        let plus = grid[Point::new(left, bottom)] == b'+';
33        let first: u64 = if plus { rows.sum() } else { rows.product() };
34        let second: u64 = if plus { cols.sum() } else { cols.product() };
35
36        right = left - 1;
37        part_one += first;
38        part_two += second;
39    }
40
41    (part_one, part_two)
42}
43
44pub fn part1(input: &Input) -> u64 {
45    input.0
46}
47
48pub fn part2(input: &Input) -> u64 {
49    input.1
50}
51
52/// Ignore spaces when parsing a number.
53fn acc(grid: &Grid<u8>, number: u64, x: i32, y: i32) -> u64 {
54    let digit = grid[Point::new(x, y)];
55    if digit == b' ' { number } else { 10 * number + digit.to_decimal::<u64>() }
56}