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;