#!/usr/bin/env perl use strict; use warnings; use v5.22; # Day 11, Part 1 use constant FLASH_LIMIT => 9; sub get_filehandle { if (@ARGV !=1) { die "Usage: $0 [input-filename]"; } my $input_filename = $ARGV[0]; open my $filehandle, '<', $input_filename or die "Could not open input file $input_filename: $!"; return $filehandle; } sub print_octopuses { # for debugging purposes my ($oct_ref, $rows, $columns) = @_; my @octopuses = @{$oct_ref}; foreach my $row (0 .. $rows - 2) { foreach my $column (0 .. $columns - 2) { print $octopuses[$row][$column]; } print "\n"; } print "\n"; } my $filehandle = get_filehandle(); # add extra column of negative infinity my @octopuses = map{ [m/\d/g, "-inf"] } <$filehandle>; my $columns = @{$octopuses[0]}; # add extra row of negative infinity push @octopuses => [ ("-inf") x $columns ]; my $rows = @octopuses; my @neighbors; foreach my $nr (-1 .. 1) { foreach my $nc (-1 .. 1) { push @neighbors => [$nr, $nc] unless ($nr == 0 && $nc == 0); } } my $flash_count = 0; foreach my $step (1 .. 100) { my @queue = (); my %flash_state = (); # 10 iterate through each octopus and increment its counter by 1 foreach my $row (0 .. $rows - 2) { foreach my $column (0 .. $columns - 2) { $octopuses[$row][$column]++; # 20 iterate through each octopus and see whether its energy level # is greater than 9 if ($octopuses[$row][$column] > FLASH_LIMIT && !exists $flash_state{$row, $column}) { # 30 for any octupus whose energy level is greater than 9 AND which # has not yet flashed in this step: # - update its state in a hash indicating that it has flashed # - increment the flash counter # - add its position to a queue which we will iterate through to # increase the energy level of adjacent octupuses $flash_state{$row, $column} = 1; $flash_count++; push @queue => [ $row, $column ]; } } } while (@queue) { my $octopus = shift @queue; my $r = $octopus->[0]; my $c = $octopus->[1]; foreach my $neighbor (@neighbors) { my $neighbor_row = $r + $neighbor->[0]; my $neighbor_col = $c + $neighbor->[1]; $octopuses[$neighbor_row][$neighbor_col]++; if ($octopuses[$neighbor_row][$neighbor_col] > FLASH_LIMIT && !exists $flash_state{$neighbor_row, $neighbor_col}) { $flash_state{$neighbor_row, $neighbor_col} = 1; $flash_count++; push @queue => [ $neighbor_row, $neighbor_col ]; } } } foreach my $row (0 .. $rows -2) { foreach my $column (0 .. $columns - 2) { if (exists $flash_state{$row, $column} && $flash_state{$row, $column} == 1) { $octopuses[$row][$column] = 0; } } } } say "part 1 flash counts = $flash_count";