]> www.fi.muni.cz Git - aoc.git/blob - 2022/42.pl
Day 21: first ugly eval-based working solution
[aoc.git] / 2022 / 42.pl
1 #!/usr/bin/perl -w
2
3 use v5.36;
4 use strict;
5
6 undef $SIG{__WARN__};
7 my %names;
8 my %vals;
9 while (<>) {
10         chomp;
11         my ($name, $rest) = split /:/;
12         $names{$name} = $rest;
13         $vals{$name} = 0+$rest if $rest =~ /\A\s*\d+\z/;
14 }
15
16 delete $vals{humn};
17 $names{humn} = 'xx';
18
19 while (!defined $vals{root}) {
20         my $added;
21         for my $n (keys %names) {
22                 no warnings;
23                 next if defined $vals{$n};
24                 my $e = $names{$n};
25                 my $d = 1;
26                 for my $v (keys %vals) {
27                         $e =~ s/$v/$vals{$v}/g;
28                         $names{$n} = $e;
29                 }
30                 next if $e =~ /[a-z]/;
31                 
32                 eval "\$vals{$n} = $e";
33                 # say "set \$vals{$n} to $vals{$n}" unless $@;
34                 $added = 1;
35         }
36         last if !$added;
37 }
38
39 for my $n (sort keys %names) {
40         say "$n = ", defined $vals{$n} ? $vals{$n} : $names{$n};
41 }
42
43 my ($val) = $names{root} =~ /(\d+)/;
44 my ($var) = $names{root} =~ /([a-z]+)/;
45 while (defined $var) {
46         say "$var = $val, var = $names{$var}";
47         my ($arg1, $op, $arg2) = $names{$var} =~ /(\w+)\s+(\S)\s+(\w+)/;
48         say "-> $arg1 $op $arg2";
49         if ($arg2 =~ /\d/) {
50                 $var = $arg1;
51                 if ($op eq '/') {
52                         $val = $val * $arg2;
53                 } elsif ($op eq '*') {
54                         $val = $val / $arg2;
55                 } elsif ($op eq '+') {
56                         $val = $val - $arg2;
57                 } elsif ($op eq '-') {
58                         $val = $val + $arg2;
59                 }
60                 say "var $var = $val";
61         } elsif ($arg1 =~ /\d/) {
62                 $var = $arg2;
63                 if ($op eq '/') {
64                         $val = $arg1 / $val;
65                 } elsif ($op eq '*') {
66                         $val = $val / $arg1;
67                 } elsif ($op eq '+') {
68                         $val = $val - $arg1;
69                 } elsif ($op eq '-') {
70                         $val = $arg1 - $val;
71                 }
72                 say "var $var = $val";
73                 if ($var eq 'humn') {
74                         $vals{humn} = $val;
75                         last;
76                 }
77         } else {
78                 last;
79         }
80 }
81 say $vals{humn};