diff options
author | Leah Neukirchen <leah@vuxu.org> | 2019-12-11 22:01:47 +0100 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2019-12-11 22:01:47 +0100 |
commit | d87d35be738179dadcade23563c39e812507573d (patch) | |
tree | e388937a764c5c314c362b6611097a00d875a9cc | |
parent | ef1d5ae6393bc198ab7b8dd5ef339fb3619427cb (diff) | |
download | adventofcode2019-d87d35be738179dadcade23563c39e812507573d.tar.gz adventofcode2019-d87d35be738179dadcade23563c39e812507573d.tar.xz adventofcode2019-d87d35be738179dadcade23563c39e812507573d.zip |
day09
-rw-r--r-- | day09.pl | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/day09.pl b/day09.pl new file mode 100644 index 0000000..d295b6a --- /dev/null +++ b/day09.pl @@ -0,0 +1,90 @@ +#!/usr/bin/perl -w +use v5.16; + +say IntCode->new('day09')->run(1); # 3063082071 +say IntCode->new('day09')->run(2); # 81348 + + +package IntCode; + +use Class::Tiny qw( input output code ip base ); +use File::Slurper 'read_text'; + +sub BUILDARGS { + my $class = shift; + return { input => [], + output => [], + code => [ split ",", read_text(shift) ], + ip => 0, + base => 0 }; +}; + +sub done { + my $self = shift; + $self->code->[$self->ip] == 99; +} + +sub pipe { + my ($self, $other) = @_; + $self->{output} = $other->{input}; + $self; +} + +sub push { + my $self = shift; + push @{$self->{input}}, @_; + $self; +} + +sub run { + my $self = shift; + $self->{input} = [ @_ ]; + until ($self->done) { + $self->step; + } + @{$self->output}; +} + +sub step { + my $self = shift; + + no warnings 'uninitialized'; + + my ($pm3, $pm2, $pm1, $op1, $op2) = + split '', sprintf("%05d", $self->code->[$self->ip]); + my $op = $op1 . $op2; + my $p1 = $pm1 == 0 ? $self->code->[$self->code->[$self->ip + 1]] + : $pm1 == 1 ? $self->code->[$self->ip + 1] + : $pm1 == 2 ? $self->code->[$self->code->[$self->ip + 1] + + $self->base] + : undef; + my $p2 = $pm2 == 0 ? $self->code->[$self->code->[$self->ip + 2]] + : $pm2 == 1 ? $self->code->[$self->ip + 2] + : $pm2 == 2 ? $self->code->[$self->code->[$self->ip + 2] + + $self->base] + : undef; + my $p3 = $pm3 == 0 ? $self->code->[$self->code->[$self->ip + 3]] + : $pm3 == 1 ? $self->code->[$self->ip + 3] + : $pm3 == 2 ? $self->code->[$self->code->[$self->ip + 3] + + $self->base] + : undef; + my $w3 = $self->code->[$self->ip+3] + ($pm3 == 2 ? $self->base : 0); + if ($op == 1) { $self->code->[$w3] = $p1 + $p2; $self->{ip} += 4; } + elsif ($op == 2) { $self->code->[$w3] = $p1 * $p2; $self->{ip} += 4; } + elsif ($op == 3) { return unless (@{$self->{input}}); # stall + $self->code->[$self->code->[$self->ip+1] + + ($pm1 == 2 ? $self->base : 0)] = + shift @{$self->{input}}; + $self->{ip} += 2; } + elsif ($op == 4) { CORE::push @{$self->{output}}, $p1; $self->{ip} += 2; } + elsif ($op == 5) { $self->{ip} = $p1 ? $p2 : $self->ip + 3; } + elsif ($op == 6) { $self->{ip} = !$p1 ? $p2 : $self->ip + 3; } + elsif ($op == 7) { $self->code->[$w3] = $p1 < $p2; $self->{ip} += 4; } + elsif ($op == 8) { $self->code->[$w3] = $p1 == $p2; $self->{ip} += 4; } + elsif ($op == 9) { $self->{base} += $p1; $self->{ip} += 2; } + else { say "INVALID OP"; } + + $self; +} + +1; |