my @lines = $*IN.lines();
my @board = @lines[0].comb.grep(/'#'|'.'/);
my %transform = @lines[2..*]».split(' => ').flat;
sub sum(@board, $offset) {
# ex. @board = (. . # . . . # . . . . # …)
@board.pairs # → (0 => ., 1 => ., 2 => #, 3 => ., …)
.grep(*.value eq '#') # → (2 => #, 6 => #, 11 => #, …)
.map(*.key - $offset) # → (4, 8, 13, …) assuming $offset = -2
.sum
}
my $nb_generations = 50000000000;
for ^$nb_generations -> $generation {
# ex. 1st iteration:
# @board = (# . . # . # . . # # . . . . . . # # # . . . # # # )
# padding → (. . . . # . . # . # . . # # . . . . . . # # # . . . # …)
# rotor → ((. . . . #) (. . . # .) (. . # . .) (. # . . #) …)
# transform → (. . # . . . # . . . . # . . . . . # . . # . . # . . … )
state $offset = 0;
my $old-offset = $offset;
my @old-board = @board;
my $first-pound = @board.first('#', :k);
my $last-pound = @board.reverse.first('#', :k);
my $left-padding = 4 - min(4, $first-pound);
my $right-padding = 4 - min(4, $last-pound);
@board.unshift('.') xx $left-padding;
@board.push('.') xx $right-padding;
@board .= rotor(5 => -4);
@board .= map({ %transform{.join} // '.' });
$offset += $left-padding - 2;
if @old-board eqv @board {
my $Δ-sum = sum(@board, $offset) - sum(@old-board, $old-offset);
my $Δ-gen = $nb_generations - $generation;
say sum(@old-board, $old-offset) + $Δ-gen × $Δ-sum;
last;
}
say sum(@board, $offset);
}