aoc2022

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

day08.pl (2812B) - raw


      1 #!/usr/local/bin/perl
      2 # day 2022-08
      3 
      4 use strict;
      5 use warnings;
      6 use v5.32;
      7 use List::Util qw( max );
      8 
      9 @ARGV = "input" unless @ARGV;
     10 chomp( my $input = do { local $/; <> } );
     11 
     12 my @trees;
     13 foreach ( split /\n/, $input ) {
     14     push @trees => [ split //, $_ ];
     15 }
     16 
     17 my $rows = scalar @trees;
     18 my $columns = scalar @{ $trees[0] };
     19 my $visible = ( 2 * $columns ) + 2 * ( $rows - 2 );
     20 my @scenic_scores;
     21 
     22 my %check = (
     23     up      => sub {
     24         my ( $x, $y ) = @_;
     25         return ( $trees[ $y ][ $x ] >
     26             max( map { $trees[ $_ ][ $x ] } ( 0 .. $y - 1 ) ) );
     27     },
     28 
     29     down    => sub {
     30         my ( $x, $y ) = @_;
     31         return ( $trees[ $y ][ $x ] >
     32             max( map { $trees[ $_ ][ $x ] } ( $y + 1 .. $rows - 1 ) ) );
     33     },
     34 
     35     left    => sub {
     36         my ( $x, $y ) = @_;
     37         return ( $trees[ $y ][ $x ] >
     38             max( map { $trees[ $y ][ $_ ] } ( 0 .. $x - 1 ) ) );
     39     },
     40 
     41     right   => sub {
     42         my ( $x, $y ) = @_;
     43         return ( $trees[ $y ][ $x ] >
     44             max( map { $trees[ $y ][ $_ ] } ( $x + 1 .. $columns - 1 ) ) );
     45     },
     46 );
     47 
     48 my %view_distance = (
     49     up      => sub {
     50         my ( $x, $y ) = @_;
     51         my $distance = 0;
     52         foreach my $yn ( reverse 0 .. $y - 1 ) {
     53             $distance++;
     54             if ( $trees[ $y ][ $x ] <= $trees[ $yn ][ $x ] ) {
     55                 last;
     56             }
     57         }
     58         return $distance;
     59     },
     60 
     61     down    => sub {
     62         my ( $x, $y ) = @_;
     63         my $distance = 0;
     64         foreach my $yn ( $y + 1 .. $rows - 1 ) {
     65             $distance++;
     66             if ( $trees[ $y ][ $x ] <= $trees[ $yn ][ $x ] ) {
     67                 last;
     68             }
     69         }
     70         return $distance;
     71     },
     72 
     73     left    => sub {
     74         my ( $x, $y ) = @_;
     75         my $distance = 0;
     76         foreach my $xn ( reverse 0 .. $x - 1 ) {
     77             $distance++;
     78             if ( $trees[ $y ][ $x ] <= $trees[ $y ][ $xn ] ) {
     79                 last;
     80             }
     81         }
     82         return $distance;
     83     },
     84 
     85     right   => sub {
     86         my ( $x, $y ) = @_;
     87         my $distance = 0;
     88         foreach my $xn ( $x + 1 .. $columns - 1 ) {
     89             $distance++;
     90             if ( $trees[ $y ][ $x ] <= $trees[ $y ][ $xn ] ) {
     91                 last;
     92             }
     93         }
     94         return $distance;
     95     },
     96 );
     97 
     98 for my $y ( 1 .. $rows - 2 ) {
     99     for my $x ( 1 .. $columns - 2 ) {
    100         foreach my $direction ( qw( up down left right ) ) {
    101             if ( $check{ $direction }->( $x, $y ) ) {
    102                 $visible++;
    103                 last;
    104             }
    105         }
    106         my $scenic_score = 1;
    107         foreach my $direction ( qw( up down left right ) ) {
    108             $scenic_score *= $view_distance{ $direction }->( $x, $y );
    109         }
    110         push @scenic_scores => $scenic_score;
    111     }
    112 }
    113 
    114 say "part 1: ", $visible;
    115 say "part 2: ", max @scenic_scores;