Day07.pm (1468B) - raw
1 package Day07; 2 3 use strict; 4 use warnings; 5 use v5.32; 6 use Scalar::Util qw(looks_like_number); 7 8 use Exporter qw( import ); 9 our @EXPORT = qw( evaluate ); 10 11 my %signal = (); 12 13 sub evaluate { 14 my ( $circuit, $index ) = @_; 15 16 # numbers evaluate to themselves 17 return $index if looks_like_number( $index ); 18 19 # return the value if we've already determined it 20 return $signal{ $index } if ( exists $signal{ $index } ); 21 22 my $operation = $circuit->{$index}; 23 24 # Direct connection, e.g. lx -> a 25 if ($operation =~ /^(\w+)$/) { 26 $signal{$index} = evaluate($circuit, $1); 27 } 28 29 # specific value 30 elsif ( $operation =~ m/\A(\d+)\z/ ) { 31 $signal{ $index } = $1; 32 } 33 34 # NOT 35 elsif ( $operation =~ m/NOT (\w+)/ ) { 36 $signal{ $index } = ~ evaluate( $circuit, $1 ); 37 } 38 39 else { 40 my ( $left, $operand, $right ) = $operation =~ m/(\w+) (\w+) (\w+)/; 41 ($left, $right) = (evaluate($circuit, $left), evaluate ($circuit, $right)); 42 43 if ( $operand eq 'AND' ) { 44 $signal{ $index } = $left & $right; 45 } elsif ( $operand eq 'OR' ) { 46 $signal{ $index } = $left | $right; 47 } elsif ( $operand eq 'LSHIFT' ) { 48 $signal{ $index } = $left << $right; 49 } elsif ( $operand eq 'RSHIFT' ) { 50 $signal{ $index } = $left >> $right; 51 } else { 52 die "Could not parse operation."; 53 } 54 } 55 56 return $signal{ $index } &= 65535; 57 } 58 59 1;