aoc2015

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

Day18.pm (3409B) - raw


      1 package Day18;
      2 
      3 use strict;
      4 use warnings;
      5 use v5.32;
      6 use Exporter qw( import );
      7 
      8 our @EXPORT = qw( init_lights flash_lights display_lights count_lights );
      9 
     10 sub setup_neighbors
     11 {
     12     my @neighbors;
     13     foreach my $nr (-1 .. 1) {
     14         foreach my $nc (-1 .. 1) {
     15             push @neighbors => [$nr, $nc] unless ($nr == 0 && $nc == 0);
     16         }
     17     }
     18     return \@neighbors;
     19 }
     20 
     21 sub init_lights
     22 {
     23     my @lights;
     24 
     25     # Define array @lights to hold initial state of lighting configuration.
     26     # Input to subroutine is string which contains puzzle input.  This string
     27     # also contains mulitple end of line separators ( \n ).  Break up each
     28     # line using split // into an array.  Pad the array with a trailing 0 to
     29     # serve as a boundary when we iterate through the array later on.  We do
     30     # this by taking advantage that the -1 index ( $lights[ -1 ] ) refers to
     31     # the last element in the array. This is important when doing comparisons
     32     # on the first element of the array as we will wrap back to the last
     33     # element which is just the extra padding.
     34     push @lights => [ ( split // ), '.' ] foreach ( split /\n/, shift );
     35 
     36     # Add an extra row at the end to serve as a boundary when we do the neighbor
     37     # comparisons later on.
     38     push @lights => [ ('.') x scalar @{ $lights[0] } ];
     39     return \@lights;
     40 }
     41 
     42 sub update_light
     43 {
     44     my $row    = shift;
     45     my $col    = shift;
     46     my @lights = @{ shift() };
     47     my @neighbors = @{ setup_neighbors() };
     48     my $neighbors_on = 0;
     49     foreach my $neighbor ( @neighbors ) {
     50         my $neighbor_row = $row + $neighbor->[0];
     51         my $neighbor_col = $col + $neighbor->[1];
     52         $neighbors_on++ if ( $lights[ $neighbor_row ][ $neighbor_col ] eq '#' );
     53     }
     54     if ( $lights[ $row ][ $col ] eq '#' ) {
     55         return ( $neighbors_on == 2 || $neighbors_on == 3 ) ? '#' : '.';
     56     } else {
     57         return ( $neighbors_on == 3 ) ? '#' : '.';
     58     }
     59 }
     60 
     61 sub flash_lights
     62 {
     63     my $current_state = shift;
     64     my $part          = shift;
     65     # need to declare a clean, new array, completely separate from $current_state
     66     # so as not to alter the current state when updating the new state
     67     my @next_state;
     68     my $rows   = scalar @{ $current_state };
     69     my $columns = scalar @{ $current_state->[ 0 ] };
     70     foreach my $row ( 0 .. $rows - 2 ) {
     71         foreach my $col ( 0 .. $columns - 2 ) {
     72             if (
     73                    ( $part == 2 ) &&
     74                    ( $row  == 0         && $col == 0            ||
     75                      $row  == 0         && $col == $columns - 2 ||
     76                      $row  == $rows - 2 && $col == 0            ||
     77                      $row  == $rows - 2 && $col == $columns - 2 )
     78                ) {
     79                      $next_state[ $row ][ $col ] = '#';
     80                  } else {
     81                      $next_state[ $row ][ $col ] = update_light( $row, $col, $current_state );
     82             }
     83         }
     84         push @{ $next_state[ $row ] } => '.'; # add trailing column back in
     85     }
     86     push @next_state => [ ('.') x $columns ]; # add trailing row back in
     87 
     88     return \@next_state;
     89 }
     90 
     91 sub display_lights # for debugging purposes only
     92 {
     93     say "@{ $_ }" foreach ( @{ shift() } );
     94 }
     95 
     96 sub count_lights
     97 {
     98     my $lights = shift;
     99     my $count = 0;
    100     foreach my $row ( @{ $lights } ) {
    101         foreach my $col ( @{ $row } ) {
    102             $count++ if ( $col eq '#' );
    103         }
    104     }
    105     return $count;
    106 }
    107 
    108 1;