]> www.fi.muni.cz Git - aoc2021.git/commitdiff
Day 24: brute force on many CPUs
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 24 Dec 2021 06:37:35 +0000 (07:37 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 24 Dec 2021 06:37:35 +0000 (07:37 +0100)
47.pl [new file with mode: 0755]
48.pl [new file with mode: 0755]

diff --git a/47.pl b/47.pl
new file mode 100755 (executable)
index 0000000..84034ae
--- /dev/null
+++ b/47.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/perl -w
+
+use v5.16;
+
+my @ins = map { chomp; [ split /\s+/ ] } <STDIN>;
+
+my %regs = (
+       x => 0,
+       y => 0,
+       z => 0,
+       w => 0,
+);
+
+# my @inp = split //, 13579246899999;
+# my @inp = (-10, 3);
+
+my %cache;
+
+sub calculate {
+       my ($ip, %regs) = @_;
+
+       my $key = join(',', $ip, $regs{w}, $regs{x}, $regs{y}, $regs{z});
+       return if $cache{$key}++;
+
+       say "calculate $ip $regs{q}"
+               if length($regs{q}) < 5;
+       while ($ip < @ins) {
+               my ($ins, $r1, $r2) = @{ $ins[$ip] };
+               my $v2 = (defined $r2 && $r2 =~ /[w-z]/) ? $regs{$r2} : $r2;
+               if ($ins eq 'inp') {
+                       if (!length($regs{q})) {
+                               $regs{q} = $regs{$r1} = shift @ARGV;
+                               say "calculate for $regs{q}";
+                       } else {
+                               for my $val (reverse '1' .. '9') {
+                                       $regs{$r1} = $val;
+                                       calculate($ip+1, %regs, q => $regs{q} . $val);
+                               }
+                       }
+               } elsif ($ins eq 'add') {
+                       $regs{$r1} += $v2;
+               } elsif ($ins eq 'mul') {
+                       $regs{$r1} *= $v2;
+               } elsif ($ins eq 'div') {
+                       $regs{$r1} /= $v2;
+                       $regs{$r1} = $regs{$r1} > 0 ? int($regs{$r1}) : -int(-$regs{$r1});
+               } elsif ($ins eq 'mod') {
+                       $regs{$r1} %= $v2;
+               } elsif ($ins eq 'eql') {
+                       $regs{$r1} = $regs{$r1} == $v2 ? 1 : 0;
+               }
+
+               # say join(' ', $ip, @{ $ins[$ip] }), "\n\tw=$regs{w} x=$regs{x} y=$regs{y} z=$regs{z}";
+               $ip++;
+       }
+       if ($regs{z} == 0) {
+               say "accepted $regs{q}";
+sleep 100_000;
+               exit 0;
+       }
+}
+
+calculate (0, %regs);
+
diff --git a/48.pl b/48.pl
new file mode 100755 (executable)
index 0000000..6aa9060
--- /dev/null
+++ b/48.pl
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -w
+
+use v5.16;
+
+my @ins = map { chomp; [ split /\s+/ ] } <STDIN>;
+
+my %regs = (
+       x => 0,
+       y => 0,
+       z => 0,
+       w => 0,
+       q => '',
+);
+
+# my @inp = split //, 13579246899999;
+# my @inp = (-10, 3);
+
+my %cache;
+
+sub calculate {
+       my ($ip, %regs) = @_;
+
+       my $key = join(',', $ip, $regs{w}, $regs{x}, $regs{y}, $regs{z});
+       return if $cache{$key}++;
+
+       say "calculate $ip $regs{q}"
+               if length($regs{q}) < 5;
+       while ($ip < @ins) {
+               my ($ins, $r1, $r2) = @{ $ins[$ip] };
+               my $v2 = (defined $r2 && $r2 =~ /[w-z]/) ? $regs{$r2} : $r2;
+               if ($ins eq 'inp') {
+                       my $v = shift @ARGV;
+                       if (defined $v) {
+                               $regs{q} .= $regs{$r1} = $v;
+                               say "calculate for $regs{q}";
+                       } else {
+                               for my $val ('1' .. '9') {
+                                       $regs{$r1} = $val;
+                                       calculate($ip+1, %regs, q => $regs{q} . $val);
+                               }
+                       }
+               } elsif ($ins eq 'add') {
+                       $regs{$r1} += $v2;
+               } elsif ($ins eq 'mul') {
+                       $regs{$r1} *= $v2;
+               } elsif ($ins eq 'div') {
+                       $regs{$r1} /= $v2;
+                       $regs{$r1} = $regs{$r1} > 0 ? int($regs{$r1}) : -int(-$regs{$r1});
+               } elsif ($ins eq 'mod') {
+                       $regs{$r1} %= $v2;
+               } elsif ($ins eq 'eql') {
+                       $regs{$r1} = $regs{$r1} == $v2 ? 1 : 0;
+               }
+
+               # say join(' ', $ip, @{ $ins[$ip] }), "\n\tw=$regs{w} x=$regs{x} y=$regs{y} z=$regs{z}";
+               $ip++;
+       }
+       if ($regs{z} == 0) {
+               say "accepted $regs{q}";
+sleep 100_000;
+               exit 0;
+       }
+}
+
+calculate (0, %regs);
+