aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Lasseter <user@4574.co.uk>2019-12-19 17:39:29 +0000
committerNat Lasseter <user@4574.co.uk>2019-12-19 17:39:29 +0000
commitd3107bc313c1cf52e7df9eb9d8ec1fe402416e3c (patch)
treecd498f79c391dbdc732744b180f5ad955bab9a05
parente13f5c8cf9a0c6d1540de00fd128337c5ba02bea (diff)
Day17
-rw-r--r--day17/Dockerfile7
-rw-r--r--day17/Makefile14
-rwxr-xr-xday17/entrypoint13
-rw-r--r--day17/input1
-rwxr-xr-xday17/part1147
-rwxr-xr-xday17/part2128
-rwxr-xr-xday17/path233
-rwxr-xr-xday17/print116
8 files changed, 659 insertions, 0 deletions
diff --git a/day17/Dockerfile b/day17/Dockerfile
new file mode 100644
index 0000000..e5adcb1
--- /dev/null
+++ b/day17/Dockerfile
@@ -0,0 +1,7 @@
+FROM ruby:2.6.5-slim
+
+WORKDIR /opt
+
+COPY . .
+
+ENTRYPOINT ["./entrypoint"]
diff --git a/day17/Makefile b/day17/Makefile
new file mode 100644
index 0000000..6a2ac45
--- /dev/null
+++ b/day17/Makefile
@@ -0,0 +1,14 @@
+DAY = 17
+
+.PHONY: run clean
+
+run: build
+ docker run -it --rm aoc2019day$(DAY)
+
+build: part* input
+ docker build -t aoc2019day$(DAY) .
+ touch build
+
+clean:
+ docker image rm -f aoc2019day$(DAY)
+ rm -f build
diff --git a/day17/entrypoint b/day17/entrypoint
new file mode 100755
index 0000000..8982d21
--- /dev/null
+++ b/day17/entrypoint
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+if [ -x part1 ] ; then
+ echo -ne "Part 1:\n\t"
+ time ./part1 < input
+fi
+if [ -x part1 -a -x part2 ] ; then
+ echo
+fi
+if [ -x part2 ] ; then
+ echo -ne "Part 2:\n\t"
+ time ./part2 < input
+fi
diff --git a/day17/input b/day17/input
new file mode 100644
index 0000000..5760778
--- /dev/null
+++ b/day17/input
@@ -0,0 +1 @@
+1,330,331,332,109,3594,1102,1182,1,15,1102,1,1487,24,1001,0,0,570,1006,570,36,1001,571,0,0,1001,570,-1,570,1001,24,1,24,1106,0,18,1008,571,0,571,1001,15,1,15,1008,15,1487,570,1006,570,14,21102,1,58,0,1106,0,786,1006,332,62,99,21101,0,333,1,21102,73,1,0,1106,0,579,1102,1,0,572,1102,0,1,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,1001,574,0,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21101,0,340,1,1106,0,177,21102,1,477,1,1106,0,177,21101,0,514,1,21101,0,176,0,1105,1,579,99,21102,184,1,0,1106,0,579,4,574,104,10,99,1007,573,22,570,1006,570,165,1001,572,0,1182,21102,375,1,1,21102,211,1,0,1106,0,579,21101,1182,11,1,21101,222,0,0,1106,0,979,21101,0,388,1,21102,233,1,0,1105,1,579,21101,1182,22,1,21102,244,1,0,1105,1,979,21102,401,1,1,21102,255,1,0,1106,0,579,21101,1182,33,1,21102,1,266,0,1105,1,979,21102,1,414,1,21101,0,277,0,1106,0,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21101,1182,0,1,21101,0,313,0,1105,1,622,1005,575,327,1101,1,0,575,21102,327,1,0,1105,1,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,12,20,0,109,4,1202,-3,1,587,20101,0,0,-1,22101,1,-3,-3,21102,1,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1106,0,597,109,-4,2106,0,0,109,5,2101,0,-4,630,20101,0,0,-2,22101,1,-4,-4,21102,1,0,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,653,20102,1,0,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,0,702,0,1106,0,786,21201,-1,-1,-1,1105,1,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21102,1,731,0,1105,1,786,1106,0,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21101,0,756,0,1106,0,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21101,0,774,0,1106,0,622,21201,-3,1,-3,1106,0,640,109,-5,2105,1,0,109,7,1005,575,802,21001,576,0,-6,20102,1,577,-5,1105,1,814,21101,0,0,-1,21101,0,0,-5,21102,1,0,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,49,-3,22201,-6,-3,-3,22101,1487,-3,-3,1202,-3,1,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21101,1,0,-1,1106,0,924,1205,-2,873,21102,35,1,-4,1105,1,924,1202,-3,1,878,1008,0,1,570,1006,570,916,1001,374,1,374,1202,-3,1,895,1102,1,2,0,1201,-3,0,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,922,20101,0,0,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,49,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,43,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1102,1,1,575,21101,973,0,0,1106,0,786,99,109,-7,2106,0,0,109,6,21102,0,1,-4,21101,0,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1105,1,1041,21102,1,-4,-2,1105,1,1041,21102,1,-5,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1202,-2,1,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,2102,1,-2,0,1105,1,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21101,439,0,1,1105,1,1150,21101,477,0,1,1105,1,1150,21101,0,514,1,21101,0,1149,0,1105,1,579,99,21102,1,1157,0,1106,0,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,1202,-5,1,1176,2102,1,-4,0,109,-6,2105,1,0,14,9,40,1,7,1,40,1,7,1,40,1,7,1,40,1,7,1,40,1,7,1,40,1,7,1,40,1,7,1,40,1,3,5,1,7,5,13,14,1,3,1,5,1,5,1,5,1,11,1,14,1,3,1,5,1,5,1,5,1,11,1,14,1,3,1,5,1,5,1,5,1,11,1,14,7,3,1,3,13,7,1,18,1,1,1,3,1,3,1,1,1,5,1,3,1,7,1,18,1,1,1,3,13,3,1,7,1,18,1,1,1,7,1,1,1,9,1,7,1,18,1,1,1,7,1,1,1,9,9,18,1,1,1,7,1,1,1,32,13,1,1,1,1,3,7,22,1,3,1,1,1,5,1,1,1,1,1,3,1,5,1,8,13,1,1,3,13,3,1,5,1,8,1,13,1,5,1,5,1,1,1,5,1,5,1,8,1,13,1,5,1,5,1,1,1,5,1,5,1,8,1,13,1,5,1,5,1,1,1,5,1,5,1,8,1,13,7,5,1,1,13,8,1,25,1,7,1,14,1,5,9,11,1,7,1,14,1,5,1,7,1,11,1,7,1,14,1,5,1,7,1,11,1,7,1,14,1,5,1,7,1,11,1,7,1,14,1,5,1,7,13,7,7,8,1,5,1,33,1,8,7,33,1,48,1,48,1,48,1,48,1,48,1,48,1,48,1,48,1,48,1,40,9,8
diff --git a/day17/part1 b/day17/part1
new file mode 100755
index 0000000..a8dc6ee
--- /dev/null
+++ b/day17/part1
@@ -0,0 +1,147 @@
+#!/usr/bin/env ruby
+
+class Machine
+ def initialize(starting_memory = [])
+ @mem = starting_memory
+ @pc = 0
+ @halt = false
+ @buffered_input = []
+ @buffered_output = []
+ @relative_base = 0
+ end
+
+ def mem(start = 0, len = @mem.length)
+ @mem[start...(start + len)]
+ end
+
+ def halt!
+ @halt = true
+ end
+
+ def halt?
+ @halt
+ end
+
+ def buffer_input(x)
+ if x.is_a?(Array) then
+ @buffered_input += x
+ else
+ @buffered_input.push(x)
+ end
+ end
+
+ def buffered_output(flush = false)
+ t = @buffered_output
+ @buffered_output = [] if flush
+ t
+ end
+
+ def step
+ return if halt?
+
+ opcode = @mem[@pc] % 100
+
+ if opcode == 99 then
+ halt!
+ @pc += 1
+ return
+ end
+
+ p3, p2, p1 = ("%03d" % (@mem[@pc] / 100)).chars
+
+ l1w, l1r = get(p1, 1)
+ l2w, l2r = get(p2, 2) if [1,2,5,6,7,8].include?(opcode)
+ l3w, l3r = get(p3, 3) if [1,2,7,8].include?(opcode)
+
+ case opcode
+ when 1
+ @mem[l3w] = l1r + l2r
+ @pc += 4
+ when 2
+ @mem[l3w] = l1r * l2r
+ @pc += 4
+ when 3
+ @mem[l1w] = @buffered_input.shift
+ @pc += 2
+ when 4
+ @buffered_output.push(l1r)
+ @pc += 2
+ when 5
+ @pc = (l1r != 0 ? l2r : @pc + 3)
+ when 6
+ @pc = (l1r == 0 ? l2r : @pc + 3)
+ when 7
+ @mem[l3w] = (l1r < l2r ? 1 : 0)
+ @pc += 4
+ when 8
+ @mem[l3w] = (l1r == l2r ? 1 : 0)
+ @pc += 4
+ when 9
+ @relative_base += l1r
+ @pc += 2
+ end
+ end
+
+ def run
+ until halt? do
+ step
+ end
+ end
+
+ private
+
+ def get(p, a)
+ w = case p
+ when "0"
+ @mem[@pc + a]
+ when "2"
+ @relative_base + @mem[@pc + a]
+ end
+ r = case p
+ when "0"
+ @mem[@mem[@pc + a]]
+ when "1"
+ @mem[@pc + a]
+ when "2"
+ @mem[@relative_base + @mem[@pc + a]]
+ end
+ [w, r || 0]
+ end
+end
+
+input = $stdin.readlines[0].strip.split(",").map(&:to_i)
+
+m = Machine.new(input)
+m.run
+grid = m.buffered_output.map(&:chr).join.lines.map(&:strip).map(&:chars).reject(&:empty?)
+scaffs = []
+
+grid.length.times do |r|
+ grid[0].length.times do |c|
+ scaffs << [c, r] unless grid[r][c] == "."
+ end
+end
+
+def count_vert(x, y, s)
+ c = 0
+ c += 1 if s.include?([x, y-1])
+ c += 1 if s.include?([x, y+1])
+ c
+end
+
+def count_horz(x, y, s)
+ c = 0
+ c += 1 if s.include?([x-1, y])
+ c += 1 if s.include?([x+1, y])
+ c
+end
+
+def intersection?(x, y, s)
+ cv = count_vert(x, y, s)
+ ch = count_horz(x, y, s)
+ [[1, 2], [2, 1], [2, 2]].include?([cv, ch])
+end
+
+inters = scaffs.select { |x, y| intersection?(x, y, scaffs) }
+
+puts inters.map{ |a,b| a * b }.sum
diff --git a/day17/part2 b/day17/part2
new file mode 100755
index 0000000..c2b8b08
--- /dev/null
+++ b/day17/part2
@@ -0,0 +1,128 @@
+#!/usr/bin/env ruby
+
+class Machine
+ def initialize(starting_memory = [])
+ @mem = starting_memory
+ @pc = 0
+ @halt = false
+ @buffered_input = []
+ @buffered_output = []
+ @relative_base = 0
+ end
+
+ def mem(start = 0, len = @mem.length)
+ @mem[start...(start + len)]
+ end
+
+ def halt!
+ @halt = true
+ end
+
+ def halt?
+ @halt
+ end
+
+ def buffer_input(x)
+ if x.is_a?(Array) then
+ @buffered_input += x
+ else
+ @buffered_input.push(x)
+ end
+ end
+
+ def buffered_output(flush = false)
+ t = @buffered_output
+ @buffered_output = [] if flush
+ t
+ end
+
+ def step
+ return if halt?
+
+ opcode = @mem[@pc] % 100
+
+ if opcode == 99 then
+ halt!
+ @pc += 1
+ return
+ end
+
+ p3, p2, p1 = ("%03d" % (@mem[@pc] / 100)).chars
+
+ l1w, l1r = get(p1, 1)
+ l2w, l2r = get(p2, 2) if [1,2,5,6,7,8].include?(opcode)
+ l3w, l3r = get(p3, 3) if [1,2,7,8].include?(opcode)
+
+ case opcode
+ when 1
+ @mem[l3w] = l1r + l2r
+ @pc += 4
+ when 2
+ @mem[l3w] = l1r * l2r
+ @pc += 4
+ when 3
+ @mem[l1w] = @buffered_input.shift
+ @pc += 2
+ when 4
+ @buffered_output.push(l1r)
+ @pc += 2
+ when 5
+ @pc = (l1r != 0 ? l2r : @pc + 3)
+ when 6
+ @pc = (l1r == 0 ? l2r : @pc + 3)
+ when 7
+ @mem[l3w] = (l1r < l2r ? 1 : 0)
+ @pc += 4
+ when 8
+ @mem[l3w] = (l1r == l2r ? 1 : 0)
+ @pc += 4
+ when 9
+ @relative_base += l1r
+ @pc += 2
+ end
+ end
+
+ def run
+ until halt? do
+ step
+ end
+ end
+
+ private
+
+ def get(p, a)
+ w = case p
+ when "0"
+ @mem[@pc + a]
+ when "2"
+ @relative_base + @mem[@pc + a]
+ end
+ r = case p
+ when "0"
+ @mem[@mem[@pc + a]]
+ when "1"
+ @mem[@pc + a]
+ when "2"
+ @mem[@relative_base + @mem[@pc + a]]
+ end
+ [w, r || 0]
+ end
+end
+
+input = $stdin.readlines[0].strip.split(",").map(&:to_i)
+input[0] = 2
+
+m = Machine.new(input)
+
+istr = <<-EOS
+A,B,A,C,B,A,C,B,A,C
+L,12,L,12,L,6,L,6
+R,8,R,4,L,12
+L,12,L,6,R,12,R,8
+n
+EOS
+
+m.buffer_input(istr.chars.map(&:ord))
+
+m.run
+puts m.buffered_output.last
diff --git a/day17/path b/day17/path
new file mode 100755
index 0000000..b6a10c9
--- /dev/null
+++ b/day17/path
@@ -0,0 +1,233 @@
+#!/usr/bin/env ruby
+
+class Machine
+ def initialize(starting_memory = [])
+ @mem = starting_memory
+ @pc = 0
+ @halt = false
+ @buffered_input = []
+ @buffered_output = []
+ @relative_base = 0
+ end
+
+ def mem(start = 0, len = @mem.length)
+ @mem[start...(start + len)]
+ end
+
+ def halt!
+ @halt = true
+ end
+
+ def halt?
+ @halt
+ end
+
+ def buffer_input(x)
+ if x.is_a?(Array) then
+ @buffered_input += x
+ else
+ @buffered_input.push(x)
+ end
+ end
+
+ def buffered_output(flush = false)
+ t = @buffered_output
+ @buffered_output = [] if flush
+ t
+ end
+
+ def step
+ return if halt?
+
+ opcode = @mem[@pc] % 100
+
+ if opcode == 99 then
+ halt!
+ @pc += 1
+ return
+ end
+
+ p3, p2, p1 = ("%03d" % (@mem[@pc] / 100)).chars
+
+ l1w, l1r = get(p1, 1)
+ l2w, l2r = get(p2, 2) if [1,2,5,6,7,8].include?(opcode)
+ l3w, l3r = get(p3, 3) if [1,2,7,8].include?(opcode)
+
+ case opcode
+ when 1
+ @mem[l3w] = l1r + l2r
+ @pc += 4
+ when 2
+ @mem[l3w] = l1r * l2r
+ @pc += 4
+ when 3
+ @mem[l1w] = @buffered_input.shift
+ @pc += 2
+ when 4
+ @buffered_output.push(l1r)
+ @pc += 2
+ when 5
+ @pc = (l1r != 0 ? l2r : @pc + 3)
+ when 6
+ @pc = (l1r == 0 ? l2r : @pc + 3)
+ when 7
+ @mem[l3w] = (l1r < l2r ? 1 : 0)
+ @pc += 4
+ when 8
+ @mem[l3w] = (l1r == l2r ? 1 : 0)
+ @pc += 4
+ when 9
+ @relative_base += l1r
+ @pc += 2
+ end
+ end
+
+ def run
+ until halt? do
+ step
+ end
+ end
+
+ private
+
+ def get(p, a)
+ w = case p
+ when "0"
+ @mem[@pc + a]
+ when "2"
+ @relative_base + @mem[@pc + a]
+ end
+ r = case p
+ when "0"
+ @mem[@mem[@pc + a]]
+ when "1"
+ @mem[@pc + a]
+ when "2"
+ @mem[@relative_base + @mem[@pc + a]]
+ end
+ [w, r || 0]
+ end
+end
+
+input = $stdin.readlines[0].strip.split(",").map(&:to_i)
+
+m = Machine.new(input)
+m.run
+grid = m.buffered_output.map(&:chr).join.lines.map(&:strip).map(&:chars).reject(&:empty?)
+
+scaffs = []
+x = 0
+y = 0
+d = 0
+
+grid.length.times do |r|
+ grid[0].length.times do |c|
+ scaffs << [c, r] unless grid[r][c] == "."
+ if %w(< ^ > v).include?(grid[r][c]) then
+ x = c
+ y = r
+ d = %w(< ^ > v).index(grid[r][c])
+ end
+ end
+end
+
+def path_end?(x, y, scaffs)
+ c = 0
+ c += 1 if scaffs.include?([x-1, y])
+ c += 1 if scaffs.include?([x+1, y])
+ c += 1 if scaffs.include?([x, y-1])
+ c += 1 if scaffs.include?([x, y+1])
+ return c == 1
+end
+
+def count(x, y, d, scaffs)
+ c = 0
+
+ case d
+ when 0
+ loop do
+ break unless scaffs.include?([x-1, y])
+ c += 1
+ x -= 1
+ end
+ when 1
+ loop do
+ break unless scaffs.include?([x, y-1])
+ c += 1
+ y -= 1
+ end
+ when 2
+ loop do
+ break unless scaffs.include?([x+1, y])
+ c += 1
+ x += 1
+ end
+ when 3
+ loop do
+ break unless scaffs.include?([x, y+1])
+ c += 1
+ y += 1
+ end
+ end
+
+ return x, y, c
+end
+
+def turn(x, y, d, scaffs)
+ d = (d + 1) % 4
+
+ case d
+ when 0
+ return d, "R" if scaffs.include?([x-1, y])
+ when 1
+ return d, "R" if scaffs.include?([x, y-1])
+ when 2
+ return d, "R" if scaffs.include?([x+1, y])
+ when 3
+ return d, "R" if scaffs.include?([x, y+1])
+ end
+
+ d = (d + 2) % 4
+ return d, "L"
+end
+
+def find_start(x, y, d, scaffs)
+ t = 0
+ loop do
+ case d
+ when 0
+ return d, t if scaffs.include?([x-1, y])
+ when 1
+ return d, t if scaffs.include?([x, y-1])
+ when 2
+ return d, t if scaffs.include?([x+1, y])
+ when 3
+ return d, t if scaffs.include?([x, y+1])
+ end
+ d = (d + 1) % 4
+ t += 1
+ end
+end
+
+path = []
+
+d, t = find_start(x, y, d, scaffs)
+case t
+when 1
+ path << "R"
+when 2
+ path << "R"
+ path << "R"
+when 3
+ path << "L"
+end
+
+loop do
+ x, y, c = count(x, y, d, scaffs)
+ path << c
+ break if path_end?(x, y, scaffs)
+ d, t = turn(x, y, d, scaffs)
+ path << t
+end
+
+p path
diff --git a/day17/print b/day17/print
new file mode 100755
index 0000000..dfbb8ca
--- /dev/null
+++ b/day17/print
@@ -0,0 +1,116 @@
+#!/usr/bin/env ruby
+
+class Machine
+ def initialize(starting_memory = [])
+ @mem = starting_memory
+ @pc = 0
+ @halt = false
+ @buffered_input = []
+ @buffered_output = []
+ @relative_base = 0
+ end
+
+ def mem(start = 0, len = @mem.length)
+ @mem[start...(start + len)]
+ end
+
+ def halt!
+ @halt = true
+ end
+
+ def halt?
+ @halt
+ end
+
+ def buffer_input(x)
+ if x.is_a?(Array) then
+ @buffered_input += x
+ else
+ @buffered_input.push(x)
+ end
+ end
+
+ def buffered_output(flush = false)
+ t = @buffered_output
+ @buffered_output = [] if flush
+ t
+ end
+
+ def step
+ return if halt?
+
+ opcode = @mem[@pc] % 100
+
+ if opcode == 99 then
+ halt!
+ @pc += 1
+ return
+ end
+
+ p3, p2, p1 = ("%03d" % (@mem[@pc] / 100)).chars
+
+ l1w, l1r = get(p1, 1)
+ l2w, l2r = get(p2, 2) if [1,2,5,6,7,8].include?(opcode)
+ l3w, l3r = get(p3, 3) if [1,2,7,8].include?(opcode)
+
+ case opcode
+ when 1
+ @mem[l3w] = l1r + l2r
+ @pc += 4
+ when 2
+ @mem[l3w] = l1r * l2r
+ @pc += 4
+ when 3
+ @mem[l1w] = @buffered_input.shift
+ @pc += 2
+ when 4
+ @buffered_output.push(l1r)
+ @pc += 2
+ when 5
+ @pc = (l1r != 0 ? l2r : @pc + 3)
+ when 6
+ @pc = (l1r == 0 ? l2r : @pc + 3)
+ when 7
+ @mem[l3w] = (l1r < l2r ? 1 : 0)
+ @pc += 4
+ when 8
+ @mem[l3w] = (l1r == l2r ? 1 : 0)
+ @pc += 4
+ when 9
+ @relative_base += l1r
+ @pc += 2
+ end
+ end
+
+ def run
+ until halt? do
+ step
+ end
+ end
+
+ private
+
+ def get(p, a)
+ w = case p
+ when "0"
+ @mem[@pc + a]
+ when "2"
+ @relative_base + @mem[@pc + a]
+ end
+ r = case p
+ when "0"
+ @mem[@mem[@pc + a]]
+ when "1"
+ @mem[@pc + a]
+ when "2"
+ @mem[@relative_base + @mem[@pc + a]]
+ end
+ [w, r || 0]
+ end
+end
+
+input = $stdin.readlines[0].strip.split(",").map(&:to_i)
+
+m = Machine.new(input)
+m.run
+puts m.buffered_output.map(&:chr).join