From: Jan "Yenya" Kasprzak <kas@fi.muni.cz>
Date: Wed, 21 Dec 2022 07:44:31 +0000 (+0100)
Subject: Day 21: slightly polished solution
X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=commitdiff_plain;h=22e31bf0848564ec5d66066308c7db2e383f6128;p=aoc.git

Day 21: slightly polished solution
---

diff --git a/2022/41.pl b/2022/41.pl
index 0603f02..3ed9afe 100755
--- a/2022/41.pl
+++ b/2022/41.pl
@@ -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');
diff --git a/2022/42.pl b/2022/42.pl
index 3611405..d5edd98 100755
--- a/2022/42.pl
+++ b/2022/42.pl
@@ -3,49 +3,49 @@
 use v5.36;
 use strict;
 
-undef $SIG{__WARN__};
-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];
+	}
 }
 
-delete $vals{humn};
-$names{humn} = 'xx';
-
-while (!defined $vals{root}) {
-	my $added;
-	for my $n (keys %names) {
-		no warnings;
-		next if defined $vals{$n};
-		my $e = $names{$n};
-		my $d = 1;
-		for my $v (keys %vals) {
-			$e =~ s/$v/$vals{$v}/g;
-			$names{$n} = $e;
-		}
-		next if $e =~ /[a-z]/;
-		
-		eval "\$vals{$n} = $e";
-		# say "set \$vals{$n} to $vals{$n}" unless $@;
-		$added = 1;
+sub walk($var) {
+	return $val{$var} if defined $val{$var};
+	return undef if !defined $expr{$var};
+	my ($arg1, $op, $arg2) = @{ $expr{$var} };
+	my $val1 = walk($arg1);
+	my $val2 = walk($arg2);
+	return undef if !defined $val1 || !defined $val2;
+	if ($op eq '+') {
+		return $val{$var} = $val1 + $val2;
+	} elsif ($op eq '-') {
+		return $val{$var} = $val1 - $val2;
+	} elsif ($op eq '*') {
+		return $val{$var} = $val1 * $val2;
+	} elsif ($op eq '/') {
+		return $val{$var} = $val1 / $val2;
 	}
-	last if !$added;
 }
 
-for my $n (sort keys %names) {
-	say "$n = ", defined $vals{$n} ? $vals{$n} : $names{$n};
-}
 
-my ($val) = $names{root} =~ /(\d+)/;
-my ($var) = $names{root} =~ /([a-z]+)/;
-while (defined $var) {
-	say "$var = $val, var = $names{$var}";
-	my ($arg1, $op, $arg2) = $names{$var} =~ /(\w+)\s+(\S)\s+(\w+)/;
-	say "-> $arg1 $op $arg2";
+delete $val{humn};
+delete $expr{humn};
+walk('root');
+my $val = $val{$expr{root}[2]};
+my $var = $expr{root}[0];
+
+while ($var ne 'humn') {
+	say "$var = $val, expr = @{ $expr{$var} }";
+	my ($arg1, $op, $arg2) = @{ $expr{$var} };
+	$arg1 = $val{$arg1} if defined $val{$arg1};
+	$arg2 = $val{$arg2} if defined $val{$arg2};
 	if ($arg2 =~ /\d/) {
 		$var = $arg1;
 		if ($op eq '/') {
@@ -57,7 +57,6 @@ while (defined $var) {
 		} elsif ($op eq '-') {
 			$val = $val + $arg2;
 		}
-		say "var $var = $val";
 	} elsif ($arg1 =~ /\d/) {
 		$var = $arg2;
 		if ($op eq '/') {
@@ -69,13 +68,11 @@ while (defined $var) {
 		} elsif ($op eq '-') {
 			$val = $arg1 - $val;
 		}
-		say "var $var = $val";
-		if ($var eq 'humn') {
-			$vals{humn} = $val;
-			last;
-		}
 	} else {
 		last;
 	}
+	say "var $var = $val";
+	$val{$var} = $val;
 }
-say $vals{humn};
+
+say $val{humn};