#!/usr/bin/perl use v5.35.0; use List::Util qw(sum); my $map_width; my @map; my @trailheads; my @peaks; while (<>) { $map_width ||= length; for (split //) { push @map, /\d/? 0+$_ : undef; push @trailheads, $#map if /0/; push @peaks, $#map if /9/; } } my @score = (0) x @map; my @reached = (-1) x @map; for my $peak (@peaks) { my @queue = $peak; while (@queue) { my $location = shift @queue; next if $reached[$location] == $peak; $reached[$location] = $peak; ++$score[$location]; my $downhill = $map[$location] - 1; for my $offset (-$map_width, 1, $map_width, -1) { my $neighbour = $location + $offset; next unless 0 <= $neighbour < @map; next unless defined $map[$neighbour]; next unless $map[$neighbour] == $downhill; push @queue, $neighbour; } } } say sum map {$score[$_]} @trailheads;