Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use List::AllUtils qw(all pairwise product);
- my @Dirs = ([-1,0], [1,0], [0,1], [0,-1]);
- # Read in data, putting border of 9s on left and right
- my @Grid = map { chomp; [9, (split //), 9] } <>;
- # Grab x size from first line and store for convenience
- my $X_SIZE = @{$Grid[0]};
- # Put 9s on top and bottom of data
- unshift @Grid, [(9) x $X_SIZE];
- push @Grid, [(9) x $X_SIZE];
- #
- # Part 1, simple scan for low points
- #
- my @lows;
- my $part1 = 0;
- foreach my $y (1 .. $#Grid - 1) {
- foreach my $x (1 .. $X_SIZE- 2) {
- my $val = $Grid[$y][$x];
- if (all { $Grid[ $y + $_->[0] ][ $x + $_->[1] ] > $val } @Dirs) {
- push( @lows, [$y,$x] );
- $part1 += ($val + 1);
- }
- }
- }
- print "Part 1: $part1\n";
- #
- # Part 2, BFS search to detect basins (sizes)
- #
- my @basins;
- my @visited;
- foreach my $low (@lows) {
- next if (defined $visited[ $low->[0] ][ $low->[1] ]);
- my $size = 0;
- my @queue = ($low);
- while (my $pos = shift @queue) {
- next if (defined $visited[$pos->[0]][$pos->[1]] or $Grid[$pos->[0]][$pos->[1]] == 9);
- $size++;
- $visited[ $pos->[0] ][ $pos->[1] ] = 1;
- my @moves = map { [pairwise {$a + $b} @$pos, @$_] } @Dirs;
- push( @queue, @moves );
- }
- push( @basins, $size );
- }
- print "Part 2: ", (product [sort {$b <=> $a} @basins]->@[0 .. 2]), "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement