diff options
author | Matias Linares <matiaslina@gmail.com> | 2019-12-10 09:29:12 -0300 |
---|---|---|
committer | Matias Linares <matiaslina@gmail.com> | 2019-12-10 09:29:12 -0300 |
commit | 8f35c2dc6516303ae0786d08cc7912ccb8218f78 (patch) | |
tree | f27e82ddd3d7044e19d964345e2991d5cbf67f00 /lib/AdventOfCode.pm6 | |
download | advent-of-code-2019-8f35c2dc6516303ae0786d08cc7912ccb8218f78.tar.gz |
Initial commit
Diffstat (limited to 'lib/AdventOfCode.pm6')
-rw-r--r-- | lib/AdventOfCode.pm6 | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/AdventOfCode.pm6 b/lib/AdventOfCode.pm6 new file mode 100644 index 0000000..cac317a --- /dev/null +++ b/lib/AdventOfCode.pm6 @@ -0,0 +1,111 @@ +use v6.d; +enum opcode ( + halt => 99, + add => 1, + multiply => 2 +); +class X::Halt is Exception {} + +class IntcodeVM is export { + has @.program; + has @.memory; + # Program counter + has $!pc = 0; + + submethod new(Str $program) { + my @program = $program.split(',').map(*.Int); + self.bless(:@program, :memory(@program)); + } + + method run { + loop { + CATCH { + when X::Halt { last } + } + self!run-next-command; + } + } + + method reset-memory { + @!memory = @.program; + $!pc = 0; + } + + method !run-next-command { + given self!peek-opcode { + when halt { + die X::Halt.new; + } + when add { + self!add(); + $!pc += 4; + } + when multiply { + self!multiply(); + $!pc += 4; + } + default { die "Unknwon opcode {self!peek-opcode()}"; } + } + } + + method !peek-opcode(--> Int) { + die "$!pc exceeds memory {@!memory.elems}" if $!pc >= @!memory.elems; + @!memory[$!pc] + } + + method !program-chunk(Range $r) { + @!memory[$r + $!pc] + } + + method !add { + my ($opcode, $mem1, $mem2, $memresult) = self!program-chunk(^4); + @!memory[$memresult] = @!memory[$mem1] + @!memory[$mem2]; + } + + method !multiply { + my ($opcode, $mem1, $mem2, $memresult) = self!program-chunk(^4); + @!memory[$memresult] = @!memory[$mem1] * @!memory[$mem2]; + } + + method output { + @!memory[0] + } +} + +sub try-inputs(IntcodeVM $vm, $noun, $verb) { + $vm.reset-memory(); + $vm.memory[1] = $noun; + $vm.memory[2] = $verb; + $vm.run; + say $vm.memory[^3]; + return $vm.memory[0]; +} + +#| First problem of day 2 +sub day2a($input-filename) is export { + my $program = slurp($input-filename); + my $vm = IntcodeVM.new($program); + # Replace bits + $vm.memory[1] = 12; + $vm.memory[2] = 2; + $vm.run; + + say "Value at position 0: {$vm.output}" +} + +sub day2b($input-filename) is export { + my $program = slurp($input-filename); + my $vm = IntcodeVM.new($program); + + for ((^100) X (^100)) -> $p { + $vm.memory[1] = $p[0]; + $vm.memory[2] = $p[1]; + $vm.run; + my $output = $vm.output; + if $output == 19690720 { + say "100 * noun + verb: {100 * $p[0] + $p[1]}"; + last; + } + $vm.reset-memory; + } +} |