]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 15: a bit polished, but still slow (43s)
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 15 Dec 2022 07:49:04 +0000 (08:49 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 15 Dec 2022 07:55:53 +0000 (08:55 +0100)
2022/29.pl
2022/30.pl

index 71896f36bef98ab61d733ded8d502ebcad1935ac..2b7128b98c265d7dee6471fdb430953696148c03 100755 (executable)
@@ -7,35 +7,29 @@ use experimental 'multidimensional';
 my $row = 2000000;
 
 my @ints;
-
 my %corr;
 
 while (<>) {
        my ($sx, $sy, $cx, $cy) = /(-?\d+)/g;
        my $r = abs($sx - $cx) + abs($sy - $cy);
        my $dist = abs($sy - $row);
-       say "dist =$dist";
-       if ($dist < $r) {
-               my $l = abs($dist-$r);
-               push @ints, [ $sx - ($r - $dist), $sx + ($r - $dist) ];
-               say "$ints[-1][0] $ints[-1][1]";
-               $corr{$cx} = 1 if $cy == $row;
-       }
+       next if $dist >= $r;
+
+       push @ints, [ $sx - ($r - $dist), $sx + ($r - $dist) ];
+       $corr{$cx} = 1 if $cy == $row;
 }
 
 @ints = sort { $a->[0] <=> $b->[0] } @ints;
-my $prev = shift @ints;
-my $sum = $prev->[1] - $prev->[0] + 1;
+my $sum = $ints[0][1] - $ints[0][0] + 1;
+my $prev = (shift @ints)->[1];
 
 for my $int (@ints) {
-       if ($int->[0] > $prev->[1]) {
+       if ($int->[0] > $prev) {
                $sum += $int->[1] - $int->[0] + 1;
-               $prev = $int;
-       } elsif ($int->[1] <= $prev->[1]) {
-               next;
-       } else {
-               $sum += $int->[1] - $prev->[1];
-               $prev = $int;
+               $prev = $int->[1];
+       } elsif ($int->[1] > $prev) {
+               $sum += $int->[1] - $prev;
+               $prev = $int->[1];
        }
 }
 
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;
 }