Advertisement
musifter

AoC 2022 day 15 (perl pt 2)

Dec 15th, 2022
2,258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.78 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use List::AllUtils  qw(min max);
  7.  
  8. $| = 1;
  9.  
  10. sub try_merge {
  11.     my ($p, $q) = @_;
  12.  
  13.     my $intStart = max ($p->[0], $q->[0]);
  14.     my $intEnd   = min ($p->[1], $q->[1]);
  15.  
  16.     if ($intStart - 1 <= $intEnd) {
  17.         return ([min ($p->[0], $q->[0]), max ($p->[1], $q->[1])]);
  18.     }
  19.  
  20.     return (0);
  21. }
  22.  
  23. my $max = 4_000_000;
  24. my @ranges;
  25.  
  26. sub add_range {
  27.     my ($y, $new_range) = @_;
  28.  
  29.     if (!$ranges[$y]) {
  30.         push( @{$ranges[$y]}, $new_range );
  31.         return;
  32.     }
  33.  
  34.     return if ($ranges[$y] == 1);
  35.     return if ($new_range->[0] > $max or $new_range->[1] < 0);
  36.  
  37.     my @new;
  38.     my $res;
  39.     my $acc = $new_range;
  40.     foreach my $r (@{$ranges[$y]}) {
  41.         $res = &try_merge( $acc, $r );
  42.         if ($res == 0) {
  43.             push( @new, $r );
  44.         } else {
  45.             $acc = $res;
  46.         }
  47.     }
  48.     push( @new, $acc );
  49.  
  50.     if ($acc->[0] <= 0 && $acc->[1] >= $max) {
  51.         $ranges[$y] = 1;
  52.     } else {
  53.         @{$ranges[$y]} = @new;
  54.     }
  55. }
  56.  
  57. foreach my $line (<>) {
  58.     my ($x, $y, $bx, $by) = ($line =~ m#(-?\d+)#g);
  59.     print $line;
  60.  
  61.     my $dist = abs( $x - $bx ) + abs( $y - $by );
  62.  
  63.     for (my $i = 1; $i <= $dist; $i++) {
  64.         my $w = $dist - $i;
  65.         &add_range( $y - $i, [$x - $w, $x + $w] ) if ($y - $i >= 0);
  66.         &add_range( $y + $i, [$x - $w, $x + $w] ) if ($y + $i <= $max);
  67.     }
  68.  
  69.     &add_range( $y, [$x - $dist, $x + $dist] ) if (0 <= $y <= $max);
  70. }
  71.  
  72. my $part2;
  73. foreach my $y (0 .. $max) {
  74.     next if ($ranges[$y] == 1);
  75.     if ($ranges[$y][0][0] - $ranges[$y][1][1] == 2) {
  76.         $part2 = 4_000_000 * ($ranges[$y][0][0] - 1) + $y;
  77.     } else {
  78.         $part2 = 4_000_000 * ($ranges[$y][1][0] - 1) + $y;
  79.     }
  80.     last;
  81. }
  82.  
  83. print "\nPart 2: $part2\n";
  84.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement