package Day07; use strict; use warnings; use v5.32; use Scalar::Util qw(looks_like_number); use Exporter qw( import ); our @EXPORT = qw( evaluate ); my %signal = (); sub evaluate { my ( $circuit, $index ) = @_; # numbers evaluate to themselves return $index if looks_like_number( $index ); # return the value if we've already determined it return $signal{ $index } if ( exists $signal{ $index } ); my $operation = $circuit->{$index}; # Direct connection, e.g. lx -> a if ($operation =~ /^(\w+)$/) { $signal{$index} = evaluate($circuit, $1); } # specific value elsif ( $operation =~ m/\A(\d+)\z/ ) { $signal{ $index } = $1; } # NOT elsif ( $operation =~ m/NOT (\w+)/ ) { $signal{ $index } = ~ evaluate( $circuit, $1 ); } else { my ( $left, $operand, $right ) = $operation =~ m/(\w+) (\w+) (\w+)/; ($left, $right) = (evaluate($circuit, $left), evaluate ($circuit, $right)); if ( $operand eq 'AND' ) { $signal{ $index } = $left & $right; } elsif ( $operand eq 'OR' ) { $signal{ $index } = $left | $right; } elsif ( $operand eq 'LSHIFT' ) { $signal{ $index } = $left << $right; } elsif ( $operand eq 'RSHIFT' ) { $signal{ $index } = $left >> $right; } else { die "Could not parse operation."; } } return $signal{ $index } &= 65535; } 1;