#!/usr/bin/env perl6
use v6.c;
class Computer
{
has @.instructions;
has Int $.pos = 0;
has Int $.counter = 0;
has %.register = :a(0), :b(0), :c(0), :d(0);
method value-of(Str() $val)
{
if ($val eq any <a b c d>) {
return %.register{$val};
}
else {
return +$val;
}
}
method run(Bool :$verbose=False)
{
my token reg { <[abcd]> };
my token val { '-'? \d+ | <[abcd]> }
while @!instructions[$!pos] {
$!counter++;
say $!pos, ' [', %.register<a b c d>.join(','), '] ', @!instructions[$!pos]
if $verbose;
given @!instructions[$!pos++] {
when /^ cpy \s+ <val> \s+ <reg> $/ {
%.register{$/<reg>} = self.value-of($/<val>);
}
when /^ inc \s+ <reg> $/ {
%.register{$/<reg>}++;
}
when /^ dec \s+ <reg> $/ {
%.register{$/<reg>}--;
}
when /^ jnz \s+ <nonzero=val> \s+ <offset=val> $/ {
if self.value-of($/<nonzero>) != 0 {
$!pos += self.value-of($/<offset>) - 1; # Compensate for ++ earlier
}
}
default {
die "Invalid instruction: $_";
}
}
}
}
}
#| AoC 2016 day 12
sub MAIN(IO() $inputfile where *.f, Bool :v(:$verbose)=False,
Int :$a=0, Int :$b=0, Int :$c=0, Int :$d=0)
{
my $computer = Computer.new(:instructions($inputfile.lines));
$computer.register<a b c d> = $a, $b, $c, $d;
$computer.run(:$verbose);
say "The state of the register: ",
$computer.register.pairs.sort.map({ "$_.key()=$_.value()"}).join(', ');
say "$computer.counter() instructions processed.";
}
Comments