]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 14: more polished solution
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 14 Dec 2023 07:45:33 +0000 (08:45 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 14 Dec 2023 08:08:21 +0000 (09:08 +0100)
2023/27.pl
2023/28.pl

index ab6cbcd40579823048fee4da74d9897b0d97b3be..d49d6b93038ee4f55e5d3163f80ef6613a63d877 100755 (executable)
@@ -7,25 +7,18 @@ my $xmax = $#{ $map[0] };
 my $ymax = $#map;
 
 my $sum;
-my $retry = 1;
-while ($retry) {
-       $retry = 0;
-for my $y (1 .. $ymax) {
+for my $y (0 .. $ymax) {
        for my $x (0 .. $xmax) {
-               if ($map[$y][$x] eq 'O' && $map[$y-1][$x] eq '.') {
-                       $map[$y-1][$x] = 'O';
+               next if $map[$y][$x] ne 'O';
+               my $y1 = $y;
+               $y1-- while $y1 && $map[$y1-1][$x] eq '.';
+               if ($y1 != $y) {
+                       $map[$y1][$x] = 'O';
                        $map[$y][$x] = '.';
-                       $retry = 1;
                }
+               $sum += $ymax + 1 - $y1;
        }
 }
-}
-       
-say join('', @$_) for @map;
 
-for my $y (0 .. $ymax) {
-       for my $x (0 .. $xmax) {
-               $sum += $ymax + 1 - $y if $map[$y][$x] eq 'O';
-       }
-}
+say join('', @$_) for @map;
 say $sum;
index 7135ca558336ee5b39994d2d2cff5c5ab335fadf..0699eb466166399800d4de012419d68b218bd3c8 100755 (executable)
@@ -7,86 +7,43 @@ my $xmax = $#{ $map[0] };
 my $ymax = $#map;
 
 my %seen;
-my @rounds;
+my @score;
 my $round;
-while (1) {
-       $round++;
-       my $retry;
-       $retry = 1;
-       while ($retry) {
-               $retry = 0;
-               for my $y (1 .. $ymax) {
-                       for my $x (0 .. $xmax) {
-                               if ($map[$y][$x] eq 'O' && $map[$y-1][$x] eq '.') {
-                                       $map[$y-1][$x] = 'O';
-                                       $map[$y][$x] = '.';
-                                       $retry = 1;
-                               }
-                       }
-               }
-       }
-       $retry = 1;
-       while ($retry) {
-               $retry = 0;
-               for my $x (1 .. $xmax) {
-                       for my $y (0 .. $ymax) {
-                               if ($map[$y][$x] eq 'O' && $map[$y][$x-1] eq '.') {
-                                       $map[$y][$x-1] = 'O';
-                                       $map[$y][$x] = '.';
-                                       $retry = 1;
-                               }
-                       }
-               }
-       }
-       $retry = 1;
-       while ($retry) {
-               $retry = 0;
-               for my $y (reverse 0 .. $ymax-1) {
+my $key;
+
+while (++$round) {
+       for (1 .. 4) {
+               for my $y (0 .. $ymax) {
                        for my $x (0 .. $xmax) {
-                               if ($map[$y][$x] eq 'O' && $map[$y+1][$x] eq '.') {
-                                       $map[$y+1][$x] = 'O';
-                                       $map[$y][$x] = '.';
-                                       $retry = 1;
-                               }
-                       }
-               }
-       }
-       $retry = 1;
-       while ($retry) {
-               $retry = 0;
-               for my $x (reverse 0 .. $xmax-1) {
-                       for my $y (0 .. $ymax) {
-                               if ($map[$y][$x] eq 'O' && $map[$y][$x+1] eq '.') {
-                                       $map[$y][$x+1] = 'O';
-                                       $map[$y][$x] = '.';
-                                       $retry = 1;
+                               next if $map[$y][$x] ne 'O';
+                               my $y1 = $y;
+                               while ($y1 && $map[$y1-1][$x] eq '.') {
+                                       $map[$y1][$x] = '.';
+                                       $map[--$y1][$x] = 'O';
                                }
                        }
                }
+
+               @map = map { # rotate clockwise
+                       my $x = $_;
+                       [ map { $map[$_][$x] } reverse 0 .. $ymax ]
+               } 0 .. $xmax;
+               ($xmax, $ymax) = ($ymax, $xmax);
        }
-               
-       # say join('', @$_) for @map;
 
-       my $sum;
+       $key = join("\n", map { join('', @$_) } @map);
+       last if $seen{$key};
+
+       my $sum = 0;
        for my $y (0 .. $ymax) {
                for my $x (0 .. $xmax) {
                        $sum += $ymax + 1 - $y if $map[$y][$x] eq 'O';
                }
        }
-       say $sum;
-       $rounds[$round] = $sum;
-       say "round $round sum $sum";
-       my $map = join("\n", map { join('', @$_) } @map);
-       if ($seen{$map}) {
-               say "round $round seen also at $seen{$map}";
-               my $period = $round - $seen{$map};
-               my $total = 1000000000;
-               $total -= $round;
-               $total %= $period;
-               say "looking at ", $round - $period + $total;
-               say $rounds[$round-$period+$total];
-               last;
-       }
-       $seen{$map} = $round;
+
+       $seen{$key} = $round;
+       $score[$round] = $sum;
 }
 
+my $remains = (1000000000 - $round) % ($round - $seen{$key});
+say $score[$seen{$key} + $remains];