]> www.fi.muni.cz Git - aoc.git/blobdiff - 2019/13.pl
First half of Year 2019
[aoc.git] / 2019 / 13.pl
diff --git a/2019/13.pl b/2019/13.pl
new file mode 100755 (executable)
index 0000000..9bdf64e
--- /dev/null
@@ -0,0 +1,91 @@
+#!/usr/bin/perl -w
+
+use v5.16;
+
+chomp (my @mem = split /,/, <>);
+
+sub m2val {
+       my ($mref, $addr, $mode) = @_;
+       if ($mode == 0) {
+               return $mref->[ $mref->[$addr] ];
+       } elsif ($mode == 1) {
+               return $mref->[$addr];
+       }
+}
+
+sub run {
+       my ($mref, $iref) = @_;
+       my @mem = @$mref;
+       my @inputs = @$iref;
+       my $pc = 0;
+       my @out;
+       while (1) {
+               my $opcode = $mem[$pc];
+               my $op = int($opcode % 100);
+               my $m1 = int($opcode / 100) % 10;
+               my $m2 = int($opcode / 1000) % 10;
+               if ($op == 1) {
+                       $mem[ $mem[$pc+3] ] = m2val(\@mem, $pc+1, $m1)
+                               + m2val(\@mem, $pc+2, $m2);
+                       $pc += 4;
+               } elsif ($op == 2) {
+                       $mem[ $mem[$pc+3] ] = m2val(\@mem, $pc+1, $m1)
+                               * m2val(\@mem, $pc+2, $m2);
+                       $pc += 4;
+               } elsif ($op == 3) {
+                       $mem[ $mem[$pc+1] ] = shift @inputs;
+                       $pc += 2;
+               } elsif ($op == 4) {
+                       push @out, m2val(\@mem, $pc+1, $m1);
+                       $pc += 2;
+               } elsif ($op == 5) {
+                       if (m2val(\@mem, $pc+1, $m1)) {
+                               $pc = m2val(\@mem, $pc+2, $m2);
+                       } else {
+                               $pc += 3;
+                       }
+               } elsif ($op == 6) {
+                       if (!m2val(\@mem, $pc+1, $m1)) {
+                               $pc = m2val(\@mem, $pc+2, $m2);
+                       } else {
+                               $pc += 3;
+                       }
+               } elsif ($op == 7) {
+                       $mem[ $mem[$pc+3] ] =
+                               m2val(\@mem, $pc+1, $m1)
+                               < m2val(\@mem, $pc+2, $m2) ? 1 : 0;
+                       $pc += 4;
+               } elsif ($op == 8) {
+                       $mem[ $mem[$pc+3] ] =
+                               m2val(\@mem, $pc+1, $m1)
+                               == m2val(\@mem, $pc+2, $m2) ? 1 : 0;
+                       $pc += 4;
+               } elsif ($op == 99) {
+                       last;
+               }
+       }
+       return @out;
+}
+
+my $max = 0;
+sub permute {
+       my ($remaining, $input) = @_;
+       for my $i (0 .. $#$remaining) {
+               my @nr = @$remaining;
+               my @in = ($nr[$i], @$input);
+               say "running with ", join(',', @in);
+               splice(@nr, $i, 1);
+               my @rv = run(\@mem, \@in);
+               if (@nr) {
+                       permute(\@nr, \@rv);
+               } else {
+                       say @rv;
+                       $max = $rv[0] if $max < $rv[0];
+               }
+       }
+}
+
+permute([ 0 .. 4 ], [0]);
+
+say $max;
+