day11-1.pl (3056B) - raw
1 #!/usr/bin/env perl 2 3 use strict; 4 use warnings; 5 use v5.22; 6 7 # Day 11, Part 1 8 9 use constant FLASH_LIMIT => 9; 10 11 sub get_filehandle { 12 if (@ARGV !=1) { 13 die "Usage: $0 [input-filename]"; 14 } 15 my $input_filename = $ARGV[0]; 16 open my $filehandle, '<', $input_filename or 17 die "Could not open input file $input_filename: $!"; 18 return $filehandle; 19 } 20 21 sub print_octopuses { # for debugging purposes 22 my ($oct_ref, $rows, $columns) = @_; 23 my @octopuses = @{$oct_ref}; 24 foreach my $row (0 .. $rows - 2) { 25 foreach my $column (0 .. $columns - 2) { 26 print $octopuses[$row][$column]; 27 } 28 print "\n"; 29 } 30 print "\n"; 31 } 32 33 my $filehandle = get_filehandle(); 34 # add extra column of negative infinity 35 my @octopuses = map{ [m/\d/g, "-inf"] } <$filehandle>; 36 my $columns = @{$octopuses[0]}; 37 # add extra row of negative infinity 38 push @octopuses => [ ("-inf") x $columns ]; 39 my $rows = @octopuses; 40 my @neighbors; 41 foreach my $nr (-1 .. 1) { 42 foreach my $nc (-1 .. 1) { 43 push @neighbors => [$nr, $nc] unless ($nr == 0 && $nc == 0); 44 } 45 } 46 my $flash_count = 0; 47 48 foreach my $step (1 .. 100) { 49 my @queue = (); 50 my %flash_state = (); 51 # 10 iterate through each octopus and increment its counter by 1 52 foreach my $row (0 .. $rows - 2) { 53 foreach my $column (0 .. $columns - 2) { 54 $octopuses[$row][$column]++; 55 # 20 iterate through each octopus and see whether its energy level 56 # is greater than 9 57 if ($octopuses[$row][$column] > FLASH_LIMIT && 58 !exists $flash_state{$row, $column}) { 59 # 30 for any octupus whose energy level is greater than 9 AND which 60 # has not yet flashed in this step: 61 # - update its state in a hash indicating that it has flashed 62 # - increment the flash counter 63 # - add its position to a queue which we will iterate through to 64 # increase the energy level of adjacent octupuses 65 $flash_state{$row, $column} = 1; 66 $flash_count++; 67 push @queue => [ $row, $column ]; 68 } 69 } 70 } 71 while (@queue) { 72 my $octopus = shift @queue; 73 my $r = $octopus->[0]; 74 my $c = $octopus->[1]; 75 foreach my $neighbor (@neighbors) { 76 my $neighbor_row = $r + $neighbor->[0]; 77 my $neighbor_col = $c + $neighbor->[1]; 78 $octopuses[$neighbor_row][$neighbor_col]++; 79 if ($octopuses[$neighbor_row][$neighbor_col] > FLASH_LIMIT && 80 !exists $flash_state{$neighbor_row, $neighbor_col}) { 81 $flash_state{$neighbor_row, $neighbor_col} = 1; 82 $flash_count++; 83 push @queue => [ $neighbor_row, $neighbor_col ]; 84 } 85 } 86 } 87 foreach my $row (0 .. $rows -2) { 88 foreach my $column (0 .. $columns - 2) { 89 if (exists $flash_state{$row, $column} && 90 $flash_state{$row, $column} == 1) { 91 $octopuses[$row][$column] = 0; 92 } 93 } 94 } 95 } 96 97 say "part 1 flash counts = $flash_count";