X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=2023%2F28.pl;fp=2023%2F28.pl;h=0699eb466166399800d4de012419d68b218bd3c8;hb=a4e1f82c3a7c63cf418e9ce63987b931792b7124;hp=7135ca558336ee5b39994d2d2cff5c5ab335fadf;hpb=9df28e43f93ba69cba3f7f56dbb1b77235ad7413;p=aoc.git diff --git a/2023/28.pl b/2023/28.pl index 7135ca5..0699eb4 100755 --- a/2023/28.pl +++ b/2023/28.pl @@ -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];