From d3107bc313c1cf52e7df9eb9d8ec1fe402416e3c Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Thu, 19 Dec 2019 17:39:29 +0000 Subject: Day17 --- day17/Dockerfile | 7 ++ day17/Makefile | 14 ++++ day17/entrypoint | 13 ++++ day17/input | 1 + day17/part1 | 147 +++++++++++++++++++++++++++++++++++ day17/part2 | 128 ++++++++++++++++++++++++++++++ day17/path | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ day17/print | 116 +++++++++++++++++++++++++++ 8 files changed, 659 insertions(+) create mode 100644 day17/Dockerfile create mode 100644 day17/Makefile create mode 100755 day17/entrypoint create mode 100644 day17/input create mode 100755 day17/part1 create mode 100755 day17/part2 create mode 100755 day17/path create mode 100755 day17/print 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 -- cgit v1.2.1