From 402edd8b37e849e408f689763b9a9748dc6884c2 Mon Sep 17 00:00:00 2001 From: Jeremy Kaplan Date: Sun, 8 Dec 2019 21:23:58 -0800 Subject: [PATCH] 2019: Day 7 Part 2 --- 2019/day7/intcode.rb | 10 ++++++- 2019/day7/part2.rb | 68 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 2019/day7/part2.rb diff --git a/2019/day7/intcode.rb b/2019/day7/intcode.rb index c0fd23e..5a6a0ae 100644 --- a/2019/day7/intcode.rb +++ b/2019/day7/intcode.rb @@ -84,20 +84,27 @@ module Intcode case operation(@mem[@ip]) when 1 add! + nil when 2 mul! + nil when 3 input!(&@input_block) + nil when 4 output!(&@output_block) when 5 branch_if_not_zero! + nil when 6 branch_if_zero! + nil when 7 less_than! + nil when 8 equal! + nil when 99 :done_executing else @@ -143,6 +150,7 @@ module Intcode output = read(@ip + 1, mode[0]) user_output.call output if block_given? @ip += 2 + output end def branch_if_not_zero! @@ -184,7 +192,7 @@ module Intcode def input if block_given? inp = yield - raise "Invalid input: #{inp}" unless inp.is_a?(Numeric) + raise "Invalid input: #{inp.inspect}" unless inp.is_a?(Numeric) return inp end diff --git a/2019/day7/part2.rb b/2019/day7/part2.rb new file mode 100644 index 0000000..218bb06 --- /dev/null +++ b/2019/day7/part2.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require_relative 'intcode' + +def inputter(queue) + idx = 0 + proc do + input = queue[idx] + idx += 1 + input + end +end + +class Amplifier + def initialize(memory, phase) + @input_queue = [phase] + @computer = Intcode::Computer.new(memory) { @input_queue.shift } + end + + def amplify(input) + @input_queue << input + output = nil + output = @computer.tick until output + output + end + + def input(val) + @input_queue << val + end +end + +def thrust(program, phases) + a = Amplifier.new(program.as_memory, phases[0]) + b = Amplifier.new(program.as_memory, phases[1]) + c = Amplifier.new(program.as_memory, phases[2]) + d = Amplifier.new(program.as_memory, phases[3]) + e = Amplifier.new(program.as_memory, phases[4]) + + cache = -Float::INFINITY + out1 = a.amplify(0) + loop do + out2 = b.amplify(out1) + out3 = c.amplify(out2) + out4 = d.amplify(out3) + out5 = e.amplify(out4) + return cache if out5 == :done_executing + + cache = out5 + out1 = a.amplify(out5) + end +end + +program = Intcode.read(File.join(__dir__, 'input')) + +phase_space = [5, 6, 7, 8, 9].permutation(5) + +max_thrust = -Float::INFINITY +max_phases = nil +phase_space.each do |phases| + t = thrust(program, phases) + next unless t > max_thrust + + max_thrust = t + max_phases = phases +end + +pp max_phases +puts max_thrust