]> www.fi.muni.cz Git - aoc.git/blobdiff - 2022/41.pl
Day 21: slightly polished solution
[aoc.git] / 2022 / 41.pl
index 0603f026de29135025ddacc9a95e09e1d0bbab09..3ed9afefb7dca3b8f9f6018a9b8be418b5739c51 100755 (executable)
@@ -3,29 +3,31 @@
 use v5.36;
 use strict;
 
-my %names;
-my %vals;
+my %expr;
+my %val;
 while (<>) {
        chomp;
-       my ($name, $rest) = split /:/;
-       $names{$name} = $rest;
-       $vals{$name} = 0+$rest if $rest =~ /\A\s*\d+\z/;
+       my ($name, $rest) = split /: /;
+       my @ops = split /\s+/, $rest;
+       if (@ops > 1) {
+               $expr{$name} = \@ops;
+       } else {
+               $val{$name} = $ops[0];
+       }
 }
 
-while (!defined $vals{root}) {
-       for my $n (keys %names) {
-               next if defined $vals{$n};
-               my $e = $names{$n};
-               my $d = 1;
-               for my $v (keys %vals) {
-                       $e =~ s/$v/$vals{$v}/g;
-               }
-               next if $e =~ /[a-z]/;
-               say "eval $e";
-               eval "\$vals{$n} = $e";
-               say "set \$vals{$n} to $vals{$n}" unless $@;
+sub walk($var) {
+       return $val{$var} if defined $val{$var};
+       my ($arg1, $op, $arg2) = @{ $expr{$var} };
+       if ($op eq '+') {
+               return $val{$var} = walk($arg1) + walk($arg2);
+       } elsif ($op eq '-') {
+               return $val{$var} = walk($arg1) - walk($arg2);
+       } elsif ($op eq '*') {
+               return $val{$var} = walk($arg1) * walk($arg2);
+       } elsif ($op eq '/') {
+               return $val{$var} = walk($arg1) / walk($arg2);
        }
-       say " ================= ";
 }
 
-say $vals{root};
+say walk('root');