--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.38;
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my $sum;
+my $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;
+ }
+ }
+}
+}
+
+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 $sum;
--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.38;
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#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;
+ }
+ }
+ }
+ }
+ $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;
+}
+