X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=2023%2F28.pl;h=f0547dd171265e0e3348d555573bd006128570e8;hb=cb7662a16eca1ff55e28338ef8ea7161224ac078;hp=7135ca558336ee5b39994d2d2cff5c5ab335fadf;hpb=9df28e43f93ba69cba3f7f56dbb1b77235ad7413;p=aoc.git diff --git a/2023/28.pl b/2023/28.pl index 7135ca5..f0547dd 100755 --- a/2023/28.pl +++ b/2023/28.pl @@ -2,91 +2,22 @@ use v5.38; -my @map = map { chomp; [ split // ] } <>; -my $xmax = $#{ $map[0] }; -my $ymax = $#map; +my $map; { local $/; $map = <>; } -my %seen; -my @rounds; -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; - } - } - } +my (@score, %seen, $round); +while (!$seen{$map}) { + $seen{$map} = $round++; + for (1 .. 4) { + my $map1; + do { # rotate the map: + $map1 .= join('', reverse $map =~ /^./gm) . "\n" + } while $map =~ s/^.//gm; + chomp ($map = $map1); + 1 while $map =~ s/O(\.+)/$1O/g; # move O's to the right } - $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) { - 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; - } - } - } - } - - # say join('', @$_) for @map; - - my $sum; - 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; + $score[$round] +=()= substr($map, pos($map)) =~ /\n/g + while $map =~ /O/g; } +my $remains = (1000000000 - $round) % ($round - $seen{$map}); +say $score[$seen{$map} + $remains];