aoc2021

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

commit f225e16c8183a8414a349b0ea5a7644110155f80
parent 8e66f05b398baf40c15fa401b840a2f8b9874753
Author: Samir Parikh <noreply@samirparikh.com>
Date:   Tue, 21 Dec 2021 17:08:53 +0000

combine programs for parts 1 and 2 into one program (day09.pl)

Diffstat:
Dday09-1.pl | 29-----------------------------
Dday09-2.pl | 77-----------------------------------------------------------------------------
Aday09.pl | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 74 insertions(+), 106 deletions(-)

diff --git a/day09-1.pl b/day09-1.pl @@ -1,29 +0,0 @@ -#!/usr/bin/env perl - -use strict; -use warnings; -use v5.22; -use Data::Dumper; - -my @heightmap = map{ [m/\d/g, 10] } <>; # add extra column of 10s -my $columns = @{$heightmap[0]}; -push @heightmap => [ (10) x $columns ]; # add extra row of 10s -my $rows = @heightmap; -my $risk_level = 0; - -foreach my $row (0 .. $rows - 2) { # don't care about last row that we added - foreach my $column (0 .. $columns - 2) { # don't care about the last column - my $height = $heightmap[$row][$column]; - my $lowpoint = 1; # true - foreach my $offset ([0, -1], [0, 1], [-1, 0], [1, 0]) { - if ($height >= - $heightmap[$row + $offset->[0]][$column + $offset->[1]]) { - $lowpoint = 0; # set to false - last; - } - } - $risk_level += $height + 1 if $lowpoint; - } -} - -say $risk_level; diff --git a/day09-2.pl b/day09-2.pl @@ -1,77 +0,0 @@ -#!/usr/bin/env perl - -use strict; -use warnings; -use v5.22; -use Data::Dumper; - -sub find_basin { - my ($row, $column, $heightmap_ref) = @_; - my $size = 1; # lowpoint is already part of basin - my @queue = ( [$row, $column] ); - while ( @queue ) { # there are still locations in queue to check - my $location = shift @queue; - my $r = $location->[0]; - my $c = $location->[1]; - my $location_height = $heightmap_ref->[$r][$c]; # can delete later - say "checking location of $r, $c with height of $location_height"; - # don't want to double-count the initial lowpoint - $heightmap_ref->[$r][$c] = 9; - # check surrounding locations for increase in height - foreach my $offset ([0, -1], [0, 1], [-1, 0], [1, 0]) { - my $neighbor_row = $r + $offset->[0]; - my $neighbor_col = $c + $offset->[1]; - my $neighbor_height = $heightmap_ref->[$neighbor_row][$neighbor_col]; - say "neighbor at $neighbor_row, $neighbor_col has height $neighbor_height"; - next if ($neighbor_height == 9); - #if ($neighbor_height == $location_height + 1) { # found increase - say "found winner"; - # add neighbor coordinates to queue and set its height to 9 to prevent - # it from being checked again (double-counted) - push @queue => [ $neighbor_row, $neighbor_col ]; # add neighbor to queue - $heightmap_ref->[$neighbor_row][$neighbor_col] = 9; - $size++; - #} - } - } - #say "row is $location->[0] and column is $location->[1]"; - #my $location_height = $heightmap_ref->[$location->[0]][$location->[1]]; - #say "recvd lowpoint of height $location_height at $row, $column"; - return $size; -} - -my @heightmap = map{ [m/\d/g, 9] } <>; # add extra column of 9s -my $columns = @{$heightmap[0]}; -push @heightmap => [ (9) x $columns ]; # add extra row of 9s -my $rows = @heightmap; -my $risk_level = 0; -my @basin_sizes; - -foreach my $row (0 .. $rows - 2) { # don't care about last row that we added - foreach my $column (0 .. $columns - 2) { # don't care about the last column - my $height = $heightmap[$row][$column]; - my $lowpoint = 1; # true - foreach my $offset ([0, -1], [0, 1], [-1, 0], [1, 0]) { - if ($height >= - $heightmap[$row + $offset->[0]][$column + $offset->[1]]) { - $lowpoint = 0; # set to false - last; - } - } - # found low point - if ($lowpoint) { - say "======================================"; - say "found lowpoint at $row, $column with height of $height"; - $risk_level += $height + 1; - my $basin_size = find_basin( $row, $column, \@heightmap ); - say "basin size is $basin_size"; - push @basin_sizes => $basin_size; - } - } -} - -say $risk_level; -# plain `sort` routine just sorts by strings in code point order -@basin_sizes = sort { $a <=> $b} @basin_sizes; -say "@basin_sizes"; -say $basin_sizes[-3] * $basin_sizes[-2] * $basin_sizes[-1]; diff --git a/day09.pl b/day09.pl @@ -0,0 +1,74 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.22; + +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 find_basin { + my ($row, $column, $heightmap_ref) = @_; + my $size = 1; # lowpoint is already part of basin + my @queue = ( [$row, $column] ); + while ( @queue ) { # there are still locations in queue to check + my $location = shift @queue; + my $r = $location->[0]; + my $c = $location->[1]; + # don't want to double-count the initial lowpoint + $heightmap_ref->[$r][$c] = 9; + # check surrounding locations for increase in height + foreach my $offset ([0, -1], [0, 1], [-1, 0], [1, 0]) { + my $neighbor_row = $r + $offset->[0]; + my $neighbor_col = $c + $offset->[1]; + my $neighbor_height = $heightmap_ref->[$neighbor_row][$neighbor_col]; + next if ($neighbor_height == 9); + # add neighbor coordinates to queue and set its height to 9 to prevent + # it from being checked again (double-counted) + push @queue => [ $neighbor_row, $neighbor_col ]; + $heightmap_ref->[$neighbor_row][$neighbor_col] = 9; + $size++; + } + } + return $size; +} + +my $filehandle = get_filehandle(); +my @heightmap = map{ [m/\d/g, 9] } <$filehandle>; # add extra column of 9s +my $columns = @{$heightmap[0]}; +push @heightmap => [ (9) x $columns ]; # add extra row of 9s +my $rows = @heightmap; +my $risk_level = 0; +my @basin_sizes; + +foreach my $row (0 .. $rows - 2) { # don't care about last row that we added + foreach my $column (0 .. $columns - 2) { # don't care about the last column + my $height = $heightmap[$row][$column]; + my $lowpoint = 1; # true + foreach my $offset ([0, -1], [0, 1], [-1, 0], [1, 0]) { + if ($height >= + $heightmap[$row + $offset->[0]][$column + $offset->[1]]) { + $lowpoint = 0; # set to false + last; + } + } + # found low point + if ($lowpoint) { + $risk_level += $height + 1; + my $basin_size = find_basin( $row, $column, \@heightmap ); + push @basin_sizes => $basin_size; + } + } +} + +say $risk_level; +# plain `sort` routine just sorts by strings in code point order +@basin_sizes = sort { $a <=> $b} @basin_sizes; +say $basin_sizes[-3] * $basin_sizes[-2] * $basin_sizes[-1];