Advertisement
musifter

AoC 2024 day 12 (Perl)

Dec 12th, 2024
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.01 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use feature         qw(say);
  7.  
  8. use Math::Vector::Real;
  9.  
  10. my ($vy,$vx) = Math::Vector::Real->canonical_base(2);
  11. my @Dirs = ($vy, $vx, -$vy, -$vx);
  12.  
  13. # Read in grid, adding sentinel ~s to right and bottom
  14. my @Grid = map { chomp; [split(//), '~'] } <>;
  15. push( @Grid, [('~') x $Grid[0]->@*] );
  16.  
  17. sub grid_at ($) { my $p = shift; return ($Grid[$p->[0]][$p->[1]]) }
  18. sub print_grid  { say "\t", join( '', @$_ ) foreach (@Grid); }
  19.  
  20. my $part1 = 0;
  21. my $part2 = 0;
  22. my %visited;
  23.  
  24. foreach my $y (0 .. $#Grid - 1) {
  25.     foreach my $x (0 .. $Grid[0]->$#* - 1) {
  26.         my $start = V($y,$x);
  27.         next if ($visited{$start});
  28.  
  29.         my $plant = grid_at($start);
  30.         my $area  = 0;
  31.         my $inner = 0;
  32.         my @queue = ($start);
  33.         my %neigh;
  34.  
  35.         while (my $pos = shift @queue) {
  36.             next if ($visited{$pos});
  37.  
  38.             my @field;
  39.             foreach my $d (@Dirs) {
  40.                 my $p = $pos + $d;
  41.                 if (grid_at($p) eq $plant) {
  42.                     push( @field, $p);
  43.                 } else {
  44.                     push( $neigh{$p}->@*, $d );
  45.                 }
  46.             }
  47.  
  48.             $inner += scalar @field;
  49.             $area++;
  50.             $visited{$pos}++;
  51.  
  52.             push( @queue, @field);
  53.         }
  54.  
  55.         my $perm = 4 * $area - $inner;
  56.         $part1 += $area * $perm;
  57.  
  58.         my %corners;
  59.         foreach my $n (keys %neigh) {
  60.             my $pos = V($n =~ m#([-0-9]+)#g);
  61.             foreach my $d ($neigh{$n}->@*) {
  62.                 my $left = V( -$d->[1], $d->[0] );
  63.                 my $corn = $pos;
  64.                 $corn += $left while (exists $neigh{$corn} and grid_at($corn - $d) eq $plant);
  65.  
  66.                 $corn -= $left;
  67.                 if (!exists $corners{$corn,$d}) {
  68.                     $corners{$corn,$d}++;
  69.                 }
  70.             }
  71.         }
  72.  
  73.         my $sides = scalar keys %corners;
  74.         $part2 += $area * $sides;
  75.  
  76.     }
  77. }
  78.  
  79. say "Part 1: $part1";
  80. say "Part 2: $part2";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement