aoc2015

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

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;