2025 AoC Day 5 – Cafeteria

This is a solution to Advent of Code 2025 day 5, written in Raku.

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

Part One

Process the database file from the new inventory management system. How many of the available ingredient IDs are fresh?

use Test;

sub day-five($input) {
    my ($ranges, $avail) = $input.IO.slurp.split("\n\n");
    my @ranges = $ranges.lines>>.split('-').map(-> ($a, $b) { +$a..+$b });
    my @avail = $avail.lines>>.Int;

    +@avail.race.grep(-> $n { $n (elem) any(@ranges) });
}

is day-five('5-test.txt'), 3, 'test input';
{
    say "Part one: ", day-five('5-input.txt');
    say "Took " ~ (now - ENTER now).base(10,2) ~ " seconds";
}
ok 1 - test input
Part one: 896
Took 0.10 seconds

Part Two

Process the database file again. How many ingredient IDs are considered to be fresh according to the fresh ingredient ID ranges?

use Test;

sub day-five($input) {
    my ($ranges, $avail) = $input.IO.slurp.split("\n\n");
    my @ranges = $ranges.lines>>.split('-').map(-> ($a, $b) { +$a..+$b });

    my @coalesced;
    RANGE:
    for @ranges -> $r {
        my $s = $r;
        my $s1 = Nil;
        for @coalesced -> $c {
            if $s.max (elem) $c {
                if $s.min (elem) $c {
                    # subset
                    next RANGE
                }
                # overlap below
                $s = $s.min..$c.min - 1;
            } elsif $s.min (elem) $c {
                # overlap above
                $s = $c.max + 1 .. $s.max;
            } elsif $s.min < $c.min and $s.max > $c.max {
                # superset
                $s1 = $c.max + 1 .. $s.max;
                $s = $s.min .. $c.min - 1;
            }
        }
        @coalesced.push($s);
        @coalesced.push($s1) if $s1;
    }

    [+] @coalesced>>.elems;
}

is day-five('5-test.txt'), 14, 'test input';
{
    say "Part two: ", day-five('5-input.txt');
    say "Took " ~ (now - ENTER now).base(10,2) ~ " seconds";
}
ok 1 - test input
Part two: 346240317247002
Took 0.04 seconds
raku