5 use experimental 'multidimensional';
7 my @map = map { chomp; [ split // ] } <>;
10 my $cols = @{ $map[0] };
11 my $periods = 1000000000;
15 while ($gen++ < $periods) {
19 for my $y (0 .. $rows-1) {
21 for my $x (0 .. $cols-1) {
22 my %count = map { $_ => 0 } ('#', '|', '.');
23 for my $neigh ([-1,-1], [0, -1], [1, -1],
25 [-1, 1], [0, 1], [1, 1]) {
26 my $nx = $x + $neigh->[0];
27 my $ny = $y + $neigh->[1];
28 next if $nx < 0 || $nx >= $cols
29 || $ny < 0 || $ny >= $cols;
30 $count{$map[$ny][$nx]}++;
32 my $self = $map[$y][$x];
33 if ($self eq '.' && $count{'|'} >= 3) {
35 } elsif ($self eq '|' && $count{'#'} >= 3) {
37 } elsif ($self eq '#' &&
38 ($count{'#'} == 0 || $count{'|'} == 0)) {
47 my $state = join('', map { join('', @$_, "\n") } @map);
49 say $total{"#"} * $total{'|'};
50 if (defined $seen{$state} && $gen < 500) {
51 say "at $gen: the same state seen at $seen{$state}";
52 my $period = $gen - $seen{$state};
54 $gen += $period * int(($periods-1-$gen)/$period);