This is a solution to Advent of Code 2024 day 10, written in Raku.
https://adventofcode.com/2024/day/10
Part One
What is the sum of the scores of all trailheads on your topographic map?
Using a recursive method, it seems easiest to walk all distinct trails from a trailhead and then save the destination coordinates so that they can be deduplicated.
For each trailhead, the solution generates a list of destination coordinates for each distinct
trail then converts it to a Set
to deduplicate the result and find the number of unique
destinations.
use Test;
sub day-ten($file, $size) {
my @grid[$size;$size] = $file.IO.lines>>.comb;
my @moves = (0, 1), (1, 0), (0, -1), (-1, 0);
sub find-trail($x, $y, $height) {
for @moves -> ($dx, $dy) {
my $x2 = $x + $dx;
my $y2 = $y + $dy;
try if @grid[$y2;$x2] == $height {
if $height == 9 {
take "$x2,$y2";
} else {
find-trail($x2, $y2, $height + 1);
}
}
}
}
my @per-trailhead = gather {
for ^$size -> $y {
for ^$size -> $x {
if @grid[$y;$x] == 0 {
my @heads = gather find-trail($x, $y, 1);
take +@heads.Set.keys;
}
}
}
}
[+] @per-trailhead
}
is day-ten('test-10.txt', 8), 36, 'example input';
say day-ten('input-10.txt', 58);
say "Took " ~ (now - ENTER now).base(10, 2) ~ "s";
ok 1 - example input 760 Took 0.33s
Part Two
What is the sum of the ratings of all trailheads?
By some good fortune, part two wants all the distinct trails that I calculated in part one, just without deduplication. The solution to part to is a slight refactor of part one to parameterise whether it is distinct-trails we want.
use Test;
sub day-ten($file, $size, :$distinct-trails = False) {
my @grid[$size;$size] = $file.IO.lines>>.comb;
my @moves = (0, 1), (1, 0), (0, -1), (-1, 0);
sub find-trail($x, $y, $height) {
for @moves -> ($dx, $dy) {
my $x2 = $x + $dx;
my $y2 = $y + $dy;
try if @grid[$y2;$x2] == $height {
if $height == 9 {
take "$x2,$y2";
} else {
find-trail($x2, $y2, $height + 1);
}
}
}
}
my @per-trailhead = gather {
for ^$size -> $y {
for ^$size -> $x {
if @grid[$y;$x] == 0 {
my @heads = gather find-trail($x, $y, 1);
if $distinct-trails {
take +@heads;
} else {
take +@heads.Set.keys;
}
}
}
}
}
[+] @per-trailhead
}
is day-ten('test-10.txt', 8), 36, 'part one';
is day-ten('test-10.txt', 8, :distinct-trails), 81, 'part two';
say 'Sum of trailhead scores: ', day-ten('input-10.txt', 58);
say 'Sum of trailhead ratings: ', day-ten('input-10.txt', 58, :distinct-trails);
say "Took " ~ (now - ENTER now).base(10, 2) ~ "s";
ok 1 - part one ok 2 - part two Sum of trailhead scores: 760 Sum of trailhead ratings: 1764 Took 0.60s