Advertisement
musifter

AoC 2021 day 9 (Perl)

Dec 8th, 2021
428
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.42 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use List::AllUtils qw(all pairwise product);
  7.  
  8. my @Dirs = ([-1,0], [1,0], [0,1], [0,-1]);
  9.  
  10. # Read in data, putting border of 9s on left and right
  11. my @Grid = map { chomp; [9, (split //), 9] } <>;
  12.  
  13. # Grab x size from first line and store for convenience
  14. my $X_SIZE = @{$Grid[0]};
  15.  
  16. # Put 9s on top and bottom of data
  17. unshift @Grid, [(9) x $X_SIZE];
  18. push @Grid, [(9) x $X_SIZE];
  19.  
  20. #
  21. # Part 1, simple scan for low points
  22. #
  23. my @lows;
  24. my $part1 = 0;
  25. foreach my $y (1 .. $#Grid - 1) {
  26. foreach my $x (1 .. $X_SIZE- 2) {
  27. my $val = $Grid[$y][$x];
  28.  
  29. if (all { $Grid[ $y + $_->[0] ][ $x + $_->[1] ] > $val } @Dirs) {
  30. push( @lows, [$y,$x] );
  31. $part1 += ($val + 1);
  32. }
  33. }
  34. }
  35.  
  36. print "Part 1: $part1\n";
  37.  
  38. #
  39. # Part 2, BFS search to detect basins (sizes)
  40. #
  41. my @basins;
  42. my @visited;
  43. foreach my $low (@lows) {
  44. next if (defined $visited[ $low->[0] ][ $low->[1] ]);
  45.  
  46. my $size = 0;
  47. my @queue = ($low);
  48.  
  49. while (my $pos = shift @queue) {
  50. next if (defined $visited[$pos->[0]][$pos->[1]] or $Grid[$pos->[0]][$pos->[1]] == 9);
  51.  
  52. $size++;
  53. $visited[ $pos->[0] ][ $pos->[1] ] = 1;
  54.  
  55. my @moves = map { [pairwise {$a + $b} @$pos, @$_] } @Dirs;
  56. push( @queue, @moves );
  57. }
  58.  
  59. push( @basins, $size );
  60. }
  61.  
  62. print "Part 2: ", (product [sort {$b <=> $a} @basins]->@[0 .. 2]), "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement