Skip to content

Commit 1bf53c9

Browse files
committed
add day 07: Amplification Circuit
1 parent 1ad0af2 commit 1bf53c9

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

07_amplification_circuit.rb

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
require_relative 'lib/intcode'
2+
3+
VERBOSE = ARGV.delete('-v')
4+
5+
def const_input(mem, phase, input)
6+
ic = Intcode.new(mem, valid_ops: (1..8).to_a + [99]).continue(input: phase)
7+
ic.continue(input: input) until ic.halted?
8+
ic.output
9+
end
10+
11+
# Assume each amplifier performs a linear mx+b transform.
12+
# Determine m and b by running the amplifiers once, instead of once per permutation.
13+
# Could take it even farther with dynamic programming:
14+
# https://www.reddit.com/r/adventofcode/comments/e7q8fp/2019_day_7_part_2_c_feed_it_forward/
15+
# But this is fast enough and I don't care.
16+
def chain(mem, phases)
17+
amps = phases.to_h { |phase| [phase, {
18+
b: b = const_input(mem, phase, 0),
19+
m: const_input(mem, phase, 1).zip(b).map { |y, bb| y - bb },
20+
}.freeze] }.freeze
21+
22+
puts amps if VERBOSE
23+
24+
sizes = amps.values.flat_map { |a| [a[:b].size, a[:m].size] }.uniq
25+
raise "Incompatible sizes #{sizes}" if sizes.size != 1
26+
27+
phases.permutation.map { |perm|
28+
ms = perm.map { |phase| amps[phase][:m] }.transpose.flatten
29+
bs = perm.map { |phase| amps[phase][:b] }.transpose.flatten
30+
ms.zip(bs).reduce(0) { |signal, (m, b)| m * signal + b }
31+
}.max
32+
end
33+
34+
input = (ARGV[0]&.include?(?,) ? ARGV[0] : ARGF.read).split(?,).map(&method(:Integer)).freeze
35+
36+
[0...5, 5...10].each { |range| puts chain(input, range.to_a) }

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Interesting approaches:
4545
* Day 02 (Intcode): Assume linearity, determine coefficients with a few runs, determine noun and verb.
4646
* Day 03 (Crossed Wires): Storing segment endpoints is faster than storing every point touched by the wires.
4747
* Day 04 (Password): Skip over entire swaths of non-increasing passwords. If considering 341234, skip straight to 344444.
48+
* Day 07 (Amplification Circuit): Assume all amplifiers perform a linear transform mx+b and determine m and b to reduce the number of times the amplifiers need to be run.
4849

4950
# Takeaways
5051

lib/intcode.rb

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ def initialize(
4242
@output = []
4343
end
4444

45+
def halted?
46+
@halt
47+
end
48+
4549
def step(
4650
input: -> { raise 'no input' },
4751
mem_range: nil, mem_start: 0, mem_len: nil, mem_all: false,

0 commit comments

Comments
 (0)