diff options
-rw-r--r-- | day09/Dockerfile | 7 | ||||
-rw-r--r-- | day09/Makefile | 14 | ||||
-rwxr-xr-x | day09/das | 73 | ||||
-rwxr-xr-x | day09/entrypoint | 13 | ||||
-rw-r--r-- | day09/input | 1 | ||||
-rwxr-xr-x | day09/part1 | 133 | ||||
-rwxr-xr-x | day09/part2 | 133 |
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 |