aoc2021

Advent of Code 2021 solutions in Perl.
git clone git://git.samirparikh.com/aoc2021
Log | Files | Refs | README

day11-2.pl (3199B) - raw


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