]> www.fi.muni.cz Git - aoc.git/blob - 2023/28.pl
Day 14: more polished solution
[aoc.git] / 2023 / 28.pl
1 #!/usr/bin/perl -w
2
3 use v5.38;
4
5 my @map = map { chomp; [ split // ] } <>;
6 my $xmax = $#{ $map[0] };
7 my $ymax = $#map;
8
9 my %seen;
10 my @score;
11 my $round;
12 my $key;
13
14 while (++$round) {
15         for (1 .. 4) {
16                 for my $y (0 .. $ymax) {
17                         for my $x (0 .. $xmax) {
18                                 next if $map[$y][$x] ne 'O';
19                                 my $y1 = $y;
20                                 while ($y1 && $map[$y1-1][$x] eq '.') {
21                                         $map[$y1][$x] = '.';
22                                         $map[--$y1][$x] = 'O';
23                                 }
24                         }
25                 }
26
27                 @map = map { # rotate clockwise
28                         my $x = $_;
29                         [ map { $map[$_][$x] } reverse 0 .. $ymax ]
30                 } 0 .. $xmax;
31                 ($xmax, $ymax) = ($ymax, $xmax);
32         }
33
34         $key = join("\n", map { join('', @$_) } @map);
35         last if $seen{$key};
36
37         my $sum = 0;
38         for my $y (0 .. $ymax) {
39                 for my $x (0 .. $xmax) {
40                         $sum += $ymax + 1 - $y if $map[$y][$x] eq 'O';
41                 }
42         }
43
44         $seen{$key} = $round;
45         $score[$round] = $sum;
46 }
47
48 my $remains = (1000000000 - $round) % ($round - $seen{$key});
49 say $score[$seen{$key} + $remains];