DEV Community

Discussion on: AoC Day 21: Chronal Conversion

Collapse
 
choroba profile image
E. Choroba

For part 1, I used the same interpreter as in the previous days. I had to convert all registers to numbers, then I just waited until the final condition could be checked.

while ($r[$ip] <= $#code) {
    $_ = 0 + $_ for @r;
    my $line = $code[ $r[$ip] ];
    my ($instruction, @args) = split ' ', $line;
    if ($r[$ip] == 28) {
        say $r[2];
        exit;
    }
    $opcodes{$instruction}->(@args);
    ++$r[$ip];
}

For part 2, the interpreter was too slow, so I rewrote the whole program by hand. Running it then took 2.5 minutes.

#!/usr/bin/perl
use strict;
use feature qw{ say };

my $prev;
my ($r0, $ip, $r2, $r3, $r4, $r5) = (0) x 6;
my %seen;

$r2 = 123;
l1:
$r2 &= 456;

$r2 = $r2 == 72;
goto l1 unless $r2;

$r2 = 0;

l6:
$r5 = 0+$r2 | 65536;
$r2 = 4843319;

l8:
$r4 = 0+$r5 & 255;
$r2 += $r4;
$r2 &= 16777215;
$r2 *= 65899;
$r2 &= 16777215;
$r4 = 256 > $r5;
goto l28 if $r4;

$r4 = 0;

l18:
$r3 = $r4 + 1;
$r3 *= 256;
$r3 = $r3 > $r5;
goto l26 if $r3;

++$r4;
goto l18;

l26:
$r5 = $r4;
goto l8;

l28:
$r4 = $r2 == $r0;
$seen{$r2}++ and end();
$prev = $r2;
end() if $r4;
goto l6;

sub end {
    say $prev;
    exit
}