aoc2021

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

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";