Fresh Ingredients by the Range

338 words
2 min.
Post preview image
Advent of Code 2025: Day 5 – counting and merging ID ranges for fresh ingredients

Day 5 brings us to the kitchen! 🥗 We have a list of ID ranges and a list of specific ingredient IDs.

The input mixes range lines (with a -) and standalone ingredient IDs:

3-5
10-14
16-20
12-18

1
5
8
11
17
32

Part 1

Part 1 asks: how many ingredient IDs fall within at least one of the given ranges?

function findFreshIngredients(idRanges: IdRange[], ingredientIds: number[]): number {
    let freshCount = 0;
    for (const id of ingredientIds)
        for (const idRange of idRanges) {
            if (id < idRange.from || id > idRange.to)
                continue;
            else {
                freshCount++;
                break;
            }
        }
    return freshCount;
}

Simple nested loop – for each ingredient ID, check all ranges and break as soon as we find a match (to avoid double-counting). From the example above, IDs 5, 11, and 17 are fresh, so the answer is 3.


Part 2

Part 2 ignores the specific ingredient IDs entirely and asks: what is the total count of distinct IDs covered across all merged ranges?

The trick here is merging overlapping (and adjacent!) ranges before counting. Sort by from, then greedily extend the current range whenever the next one starts at or before last.to + 1 (the +1 handles adjacent ranges like 3-5 and 6-8 which together cover 3-8):

function findTotalFreshIngredientCount(idRanges: IdRange[], _: number[]): number {
    const sorted = idRanges.slice().sort((a, b) => a.from - b.from);
    const merged: IdRange[] = [];

    for (const range of sorted) {
        const last = merged[merged.length - 1];
        if (last && range.from <= last.to + 1) {
            last.to = Math.max(last.to, range.to);
        } else {
            merged.push({ ...range });
        }
    }

    return merged.reduce((sum, r) => sum + (r.to - r.from + 1), 0);
}

For the test input, ranges 10-14, 12-18, and 16-20 overlap and merge into 10-20. Adding 3-5 gives a total coverage of 3 + 11 = 14 IDs.


Unrolling the Paper Rolls
Grant Calculations in Two Formats