From a4e1f82c3a7c63cf418e9ce63987b931792b7124 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Thu, 14 Dec 2023 08:45:33 +0100 Subject: [PATCH] Day 14: more polished solution --- 2023/27.pl | 23 +++++-------- 2023/28.pl | 95 +++++++++++++++--------------------------------------- 2 files changed, 34 insertions(+), 84 deletions(-) diff --git a/2023/27.pl b/2023/27.pl index ab6cbcd..d49d6b9 100755 --- a/2023/27.pl +++ b/2023/27.pl @@ -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; 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]; -- 2.43.5