aboutsummaryrefslogtreecommitdiff
path: root/day09
diff options
context:
space:
mode:
authorNat Lasseter <user@4574.co.uk>2019-12-09 10:16:15 +0000
committerNat Lasseter <user@4574.co.uk>2019-12-09 10:16:15 +0000
commitc8d92acd37d553e98ec312ca172c374138d7798a (patch)
treec1f1030468a7a962ae86c20c8354035f18006fbe /day09
parenta5367fdb1b0d77c1ac6f23380a409df9ce54792d (diff)
Day 09
Diffstat (limited to 'day09')
-rw-r--r--day09/Dockerfile7
-rw-r--r--day09/Makefile14
-rwxr-xr-xday09/das73
-rwxr-xr-xday09/entrypoint13
-rw-r--r--day09/input1
-rwxr-xr-xday09/part1133
-rwxr-xr-xday09/part2133
7 files changed, 374 insertions, 0 deletions
diff --git a/day09/Dockerfile b/day09/Dockerfile
new file mode 100644
index 0000000..e5adcb1
--- /dev/null
+++ b/day09/Dockerfile
@@ -0,0 +1,7 @@
+FROM ruby:2.6.5-slim
+
+WORKDIR /opt
+
+COPY . .
+
+ENTRYPOINT ["./entrypoint"]
diff --git a/day09/Makefile b/day09/Makefile
new file mode 100644
index 0000000..9ba2334
--- /dev/null
+++ b/day09/Makefile
@@ -0,0 +1,14 @@
+DAY = 09
+
+.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/day09/das b/day09/das
new file mode 100755
index 0000000..9b1eecf
--- /dev/null
+++ b/day09/das
@@ -0,0 +1,73 @@
+#!/usr/bin/env ruby
+
+class Program
+ def initialize(program)
+ @mem = program
+ @pc = 0
+ end
+
+ def dis_next
+ opcode = @mem[@pc] % 100
+
+ p3, p2, p1 = ("%03d" % (@mem[@pc] / 100)).chars
+
+ print "#{@pc}: "
+ case opcode
+ when 1
+ puts "add #{Program.sigil(p1)}#{@mem[@pc+1]} #{Program.sigil(p2)}#{@mem[@pc+2]} #{Program.sigil(p3)}#{@mem[@pc+3]}"
+ @pc += 4
+ when 2
+ puts "mul #{Program.sigil(p1)}#{@mem[@pc+1]} #{Program.sigil(p2)}#{@mem[@pc+2]} #{Program.sigil(p3)}#{@mem[@pc+3]}"
+ @pc += 4
+ when 3
+ puts "in #{Program.sigil(p1)}#{@mem[@pc+1]}"
+ @pc += 2
+ when 4
+ puts "out #{Program.sigil(p1)}#{@mem[@pc+1]}"
+ @pc += 2
+ when 5
+ puts "jnz #{Program.sigil(p1)}#{@mem[@pc+1]} #{Program.sigil(p2)}#{@mem[@pc+2]}"
+ @pc += 3
+ when 6
+ puts "jez #{Program.sigil(p1)}#{@mem[@pc+1]} #{Program.sigil(p2)}#{@mem[@pc+2]}"
+ @pc += 3
+ when 7
+ puts "tlt #{Program.sigil(p1)}#{@mem[@pc+1]} #{Program.sigil(p2)}#{@mem[@pc+2]} #{Program.sigil(p3)}#{@mem[@pc+3]}"
+ @pc += 4
+ when 8
+ puts "teq #{Program.sigil(p1)}#{@mem[@pc+1]} #{Program.sigil(p2)}#{@mem[@pc+2]} #{Program.sigil(p3)}#{@mem[@pc+3]}"
+ @pc += 4
+ when 9
+ puts "arb #{Program.sigil(p1)}#{@mem[@pc+1]}"
+ @pc += 2
+ when 99
+ puts "hlt"
+ @pc += 1
+ else
+ puts "dat #{@mem[@pc]}"
+ @pc += 1
+ end
+ end
+
+ def dis_all
+ until @pc >= @mem.length do
+ dis_next
+ end
+ end
+
+ private
+
+ def self.sigil(p)
+ case p
+ when "0"
+ "@"
+ when "2"
+ "&"
+ end
+ end
+end
+
+input = $stdin.readlines[0].strip.split(",").map(&:to_i)
+
+p = Program.new(input)
+p.dis_all
diff --git a/day09/entrypoint b/day09/entrypoint
new file mode 100755
index 0000000..8982d21
--- /dev/null
+++ b/day09/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/day09/input b/day09/input
new file mode 100644
index 0000000..89aa1ce
--- /dev/null
+++ b/day09/input
@@ -0,0 +1 @@
+1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,3,1,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,38,1003,1102,24,1,1008,1102,1,29,1009,1102,873,1,1026,1102,1,32,1015,1102,1,1,1021,1101,0,852,1023,1102,1,21,1006,1101,35,0,1018,1102,1,22,1019,1102,839,1,1028,1102,1,834,1029,1101,0,36,1012,1101,0,31,1011,1102,23,1,1000,1101,405,0,1024,1101,33,0,1013,1101,870,0,1027,1101,0,26,1005,1101,30,0,1004,1102,1,39,1007,1101,0,28,1017,1101,34,0,1001,1102,37,1,1014,1101,20,0,1002,1102,1,0,1020,1101,0,859,1022,1102,1,27,1016,1101,400,0,1025,1102,1,25,1010,109,-6,1207,10,29,63,1005,63,201,1001,64,1,64,1105,1,203,4,187,1002,64,2,64,109,3,2107,25,8,63,1005,63,221,4,209,1106,0,225,1001,64,1,64,1002,64,2,64,109,-4,2101,0,9,63,1008,63,18,63,1005,63,245,1106,0,251,4,231,1001,64,1,64,1002,64,2,64,109,3,2108,38,7,63,1005,63,273,4,257,1001,64,1,64,1106,0,273,1002,64,2,64,109,22,21102,40,1,0,1008,1018,40,63,1005,63,299,4,279,1001,64,1,64,1106,0,299,1002,64,2,64,109,-16,21108,41,41,10,1005,1012,321,4,305,1001,64,1,64,1105,1,321,1002,64,2,64,109,6,2102,1,-2,63,1008,63,22,63,1005,63,341,1105,1,347,4,327,1001,64,1,64,1002,64,2,64,109,21,1206,-8,359,1106,0,365,4,353,1001,64,1,64,1002,64,2,64,109,-7,21101,42,0,-6,1008,1016,44,63,1005,63,389,1001,64,1,64,1105,1,391,4,371,1002,64,2,64,109,2,2105,1,0,4,397,1106,0,409,1001,64,1,64,1002,64,2,64,109,-3,1205,0,427,4,415,1001,64,1,64,1105,1,427,1002,64,2,64,109,-13,2102,1,-1,63,1008,63,39,63,1005,63,449,4,433,1106,0,453,1001,64,1,64,1002,64,2,64,109,-10,1202,4,1,63,1008,63,20,63,1005,63,479,4,459,1001,64,1,64,1106,0,479,1002,64,2,64,109,7,2108,37,-2,63,1005,63,495,1105,1,501,4,485,1001,64,1,64,1002,64,2,64,109,4,21101,43,0,1,1008,1010,43,63,1005,63,523,4,507,1106,0,527,1001,64,1,64,1002,64,2,64,109,-4,1208,-5,23,63,1005,63,549,4,533,1001,64,1,64,1106,0,549,1002,64,2,64,109,-4,1208,7,27,63,1005,63,565,1106,0,571,4,555,1001,64,1,64,1002,64,2,64,109,15,1205,4,587,1001,64,1,64,1106,0,589,4,577,1002,64,2,64,109,-7,1202,-7,1,63,1008,63,18,63,1005,63,613,1001,64,1,64,1106,0,615,4,595,1002,64,2,64,109,5,21107,44,43,1,1005,1015,635,1001,64,1,64,1105,1,637,4,621,1002,64,2,64,109,-2,21102,45,1,6,1008,1018,44,63,1005,63,661,1001,64,1,64,1105,1,663,4,643,1002,64,2,64,109,-18,1207,6,24,63,1005,63,685,4,669,1001,64,1,64,1105,1,685,1002,64,2,64,109,4,2101,0,8,63,1008,63,21,63,1005,63,707,4,691,1105,1,711,1001,64,1,64,1002,64,2,64,109,17,1206,5,725,4,717,1105,1,729,1001,64,1,64,1002,64,2,64,109,9,21107,46,47,-9,1005,1015,751,4,735,1001,64,1,64,1106,0,751,1002,64,2,64,109,-9,1201,-6,0,63,1008,63,26,63,1005,63,775,1001,64,1,64,1106,0,777,4,757,1002,64,2,64,109,-15,1201,0,0,63,1008,63,23,63,1005,63,803,4,783,1001,64,1,64,1105,1,803,1002,64,2,64,109,-1,2107,30,10,63,1005,63,819,1106,0,825,4,809,1001,64,1,64,1002,64,2,64,109,24,2106,0,5,4,831,1105,1,843,1001,64,1,64,1002,64,2,64,109,-5,2105,1,5,1001,64,1,64,1105,1,861,4,849,1002,64,2,64,109,14,2106,0,-5,1105,1,879,4,867,1001,64,1,64,1002,64,2,64,109,-17,21108,47,44,4,1005,1019,899,1001,64,1,64,1105,1,901,4,885,4,64,99,21101,0,27,1,21102,915,1,0,1106,0,922,21201,1,58969,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,0,942,0,1105,1,922,22102,1,1,-1,21201,-2,-3,1,21101,957,0,0,1106,0,922,22201,1,-1,-2,1106,0,968,21201,-2,0,-2,109,-3,2105,1,0
diff --git a/day09/part1 b/day09/part1
new file mode 100755
index 0000000..6e887bd
--- /dev/null
+++ b/day09/part1
@@ -0,0 +1,133 @@
+#!/usr/bin/env ruby
+
+class Machine
+ def initialize(starting_memory = [])
+ @mem = starting_memory
+ @pc = 0
+ @halt = false
+ @wait = 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 wait!
+ @wait = true
+ end
+
+ def wait?
+ t = @wait
+ @wait = false
+ t
+ end
+
+ def buffer_input(x)
+ if x.is_a?(Array) then
+ @buffered_input += x
+ else
+ @buffered_input.push(x)
+ end
+ end
+
+ def buffered_output
+ t = @buffered_output
+ @buffered_output = []
+ 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
+ if @buffered_input.empty? then
+ wait!
+ return
+ end
+ @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? || wait? 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.buffer_input(1)
+
+m.run
+puts m.buffered_output
diff --git a/day09/part2 b/day09/part2
new file mode 100755
index 0000000..abf7a80
--- /dev/null
+++ b/day09/part2
@@ -0,0 +1,133 @@
+#!/usr/bin/env ruby
+
+class Machine
+ def initialize(starting_memory = [])
+ @mem = starting_memory
+ @pc = 0
+ @halt = false
+ @wait = 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 wait!
+ @wait = true
+ end
+
+ def wait?
+ t = @wait
+ @wait = false
+ t
+ end
+
+ def buffer_input(x)
+ if x.is_a?(Array) then
+ @buffered_input += x
+ else
+ @buffered_input.push(x)
+ end
+ end
+
+ def buffered_output
+ t = @buffered_output
+ @buffered_output = []
+ 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
+ if @buffered_input.empty? then
+ wait!
+ return
+ end
+ @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? || wait? 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.buffer_input(2)
+
+m.run
+puts m.buffered_output