]> www.fi.muni.cz Git - aoc.git/blobdiff - 2022/30.pl
Day 15: a bit polished, but still slow (43s)
[aoc.git] / 2022 / 30.pl
index 3dc0e5f4fc0adce2a388a824a2bb090c0372f8db..0c3bb5aae8ebeb63ff211126c350cab2ea20ad93 100755 (executable)
@@ -4,54 +4,44 @@ use v5.36;
 use strict;
 use experimental 'multidimensional';
 
-my $row = 2000000;
 my $max = 4000000;
 
-my @input = <>;
+my @input = map {
+       my ($x, $y, $cx, $cy) = /(-?\d+)/g;
+       [ $x, $y, abs($x-$cx) + abs($y-$cy) ]
+} <>;
 
 sub compute_row($row) {
        my @ints;
-       my %corr;
 
        for (@input) {
-               my ($sx, $sy, $cx, $cy) = /(-?\d+)/g;
-               my $r = abs($sx - $cx) + abs($sy - $cy);
+               my ($sx, $sy, $r) = @$_;
                my $dist = abs($sy - $row);
-               # say "dist =$dist";
-               if ($dist < $r) {
-                       my ($l, $r) = ($sx - ($r - $dist), $sx + ($r - $dist));
-                       next if $r < 0 || $l > $max;
-                       $l = 0 if $l < 0;
-                       $r = $max if $r > $max;
-                       push @ints, [$l, $r];
-                       # say "$ints[-1][0] $ints[-1][1]";
-                       $corr{$cx} = 1 if $cy == $row;
-               }
+               next if $dist > $r;
+
+               my ($left, $right) = ($sx - ($r - $dist), $sx + ($r - $dist));
+               next if $right < 0 || $left > $max;
+               $left = 0 if $left < 0;
+               $right = $max if $right > $max;
+               push @ints, [$left, $right];
        }
 
        @ints = sort { $a->[0] <=> $b->[0] } @ints;
-       my $prev = shift @ints;
-       if ($prev->[0]) {
-               say "at 0 $row";
-               exit 0;
-       }
-       my $sum = $prev->[1] - $prev->[0] + 1;
+       my $prev = (shift @ints)->[1];
 
        for my $int (@ints) {
-               if ($int->[0] < $max && $int->[0] > $prev->[1]+1) {
-                       say "at ", $prev->[1]+1, " $row: ", 4000000*($prev->[1]+1)+$row;
+               next if $int->[1] <= $prev;
+               if ($int->[0] > $prev+1) {
+                       say "at ", $prev+1, " $row: ",
+                               4000000*($prev+1)+$row;
                        exit 0;
-               } elsif ($int->[1] <= $prev->[1]) {
-                       next;
-               } else {
-                       $prev = $int;
                }
-               last if $prev->[1] > $max;
+               $prev = $int->[1];
        }
 }
 
-for (1 .. $max) {
+for (0 .. $max) {
        compute_row($_);
-       say "row $_" if $_ % 1000 == 0;
+       say "row $_" if $_ % 10_000 == 0;
 }