Day 05 - Cafeteria

rangesintervalsmergesweepparsing

Language: Rust

Problem https://adventofcode.com/2025/day/5


Part 1: The input has two sections: a list of inclusive ranges like 3-5, then a list of ingredient IDs. The question is how many of those IDs fall inside any of the ranges.

Simple enough. Parse the ranges into (start, end) pairs, parse the IDs, then check each one against all ranges:

let fresh = ids.filter(|id| {
    ranges.iter().any(|(s, e)| id >= s && id <= e)
}).count();

Brute force, but the input is small so it runs instantly.


Part 2: Now the question is how many distinct values are covered by the ranges themselves. Overlapping ranges shouldn’t be counted twice. Small wording change, completely different problem.

Brute force was the first instinct and the wrong one. The clean solution is interval merging: sort ranges by start, then walk through and merge anything that overlaps or touches. Ranges are inclusive so size is end - start + 1, and touching ranges (start == merged_end + 1) must merge too or you undercount.

ranges.sort_by_key(|&(start, _end)| start);

let (mut merged_start, mut merged_end) = ranges[0];
let mut total_covered = 0;

for (start, end) in ranges.into_iter().skip(1) {
    if start <= merged_end + 1 {
        if end > merged_end {
            merged_end = end;
        }
    } else {
        total_covered += merged_end - merged_start + 1;
        merged_start = start;
        merged_end = end;
    }
}

total_covered += merged_end - merged_start + 1;

Once you see it as an interval problem, the solution is actually pretty clean.


Solution: https://github.com/Elyrial/AdventOfCode/blob/main/src/solutions/year2025/day05.rs

No C writeup yet.