Skip to content

Commit 3665f99

Browse files
committed
Working part two!
Took a while due to the bug I had in the computer `run`. That is, after I halt, I should _not_ parse the next op, because after a halt, we don't have a guarantee that the current memory is a valid op.
1 parent b420cbf commit 3665f99

File tree

3 files changed

+117
-21
lines changed

3 files changed

+117
-21
lines changed

2019/7/README.md

+42-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Answers
22

3-
| Part 1 | Part 2 |
4-
|---------|-----------|
5-
| `87138` | ` ` |
3+
| Part 1 | Part 2 |
4+
|---------|------------|
5+
| `87138` | `17279674` |
66

77
## --- Day 7: Amplification Circuit ---
88

@@ -49,3 +49,42 @@ Here are some example programs:
4949

5050

5151
Try every combination of phase settings on the amplifiers. _What is the highest signal that can be sent to the thrusters?_
52+
53+
-----------------
54+
55+
## --- Part Two ---
56+
57+
It's no good - in this configuration, the amplifiers can't generate a large enough output signal to produce the thrust you'll need. The Elves quickly talk you through rewiring the amplifiers into a _feedback loop_:
58+
59+
O-------O O-------O O-------O O-------O O-------O
60+
0 -+->| Amp A |->| Amp B |->| Amp C |->| Amp D |->| Amp E |-.
61+
| O-------O O-------O O-------O O-------O O-------O |
62+
| |
63+
'--------------------------------------------------------+
64+
|
65+
v
66+
(to thrusters)
67+
68+
69+
Most of the amplifiers are connected as they were before; amplifier `A`'s output is connected to amplifier `B`'s input, and so on. _However,_ the output from amplifier `E` is now connected into amplifier `A`'s input. This creates the feedback loop: the signal will be sent through the amplifiers _many times_.
70+
71+
In feedback loop mode, the amplifiers need _totally different phase settings_: integers from `5` to `9`, again each used exactly once. These settings will cause the Amplifier Controller Software to repeatedly take input and produce output many times before halting. Provide each amplifier its phase setting at its first input instruction; all further input/output instructions are for signals.
72+
73+
Don't restart the Amplifier Controller Software on any amplifier during this process. Each one should continue receiving and sending signals until it halts.
74+
75+
All signals sent or received in this process will be between pairs of amplifiers except the very first signal and the very last signal. To start the process, a `0` signal is sent to amplifier `A`'s input _exactly once_.
76+
77+
Eventually, the software on the amplifiers will halt after they have processed the final loop. When this happens, the last output signal from amplifier `E` is sent to the thrusters. Your job is to _find the largest output signal that can be sent to the thrusters_ using the new phase settings and feedback loop arrangement.
78+
79+
Here are some example programs:
80+
81+
* Max thruster signal _`139629729`_ (from phase setting sequence `9,8,7,6,5`):
82+
83+
3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
84+
85+
* Max thruster signal _`18216`_ (from phase setting sequence `9,7,8,5,6`):
86+
87+
3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
88+
89+
90+
Try every combination of the new phase settings on the amplifier feedback loop. _What is the highest signal that can be sent to the thrusters?_

2019/7/circuit.js

+62-17
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ const POSITION_MODE = '0';
1212
const IMMEDIATE_MODE = '1';
1313

1414
class Computer {
15-
constructor(memory, inputs, clone_memory = false) {
15+
constructor(memory, inputs, id, clone_memory = false) {
16+
// For debugging
17+
this.id = String.fromCharCode('A'.charCodeAt(0) + id);
18+
1619
this.original_memory = clone_memory && memory.slice(0);
1720
this.memory = memory.slice(0);
1821
this.pointer = 0;
@@ -51,7 +54,7 @@ class Computer {
5154
[STP]: {
5255
name: STP,
5356
params: 0,
54-
fn: (...a) => console.log('STOP', a),
57+
fn: () => (this.halted = true),
5558
},
5659

5760
[JIT]: {
@@ -94,13 +97,22 @@ class Computer {
9497
write: true,
9598
},
9699
};
100+
101+
this.halted = false;
97102
}
98103

99104
run() {
100105
let op = this.parseOp();
101106

102-
while (op.name !== STP) {
107+
while (!this.halted) {
103108
this.runOp(op);
109+
110+
// Pause executing the computer so this output can be given to the next computer
111+
// Additionally, break if we've halted
112+
if (op.name === OUT || this.halted) {
113+
break;
114+
}
115+
104116
op = this.parseOp();
105117
}
106118

@@ -153,30 +165,63 @@ class Computer {
153165
}
154166

155167
// For debugging
156-
// get _() {
157-
// return this.input.slice(Math.max(0, this.pointer - 1), this.pointer + 8);
158-
// }
168+
get _() {
169+
return this.memory.slice(
170+
Math.max(0, this.pointer - 1),
171+
this.pointer + 8
172+
);
173+
}
159174
}
160175

161176
class Circuit {
162-
constructor(memory, phase_settings) {
177+
constructor(memory, phase_settings, circuit_size = 5) {
163178
this.memory = memory;
164179
this.phase_settings = phase_settings;
180+
this.circuit = Array(circuit_size)
181+
.fill()
182+
.map((c, i) => {
183+
let phase_setting = [phase_settings[i]];
184+
if (i === 0) {
185+
// "The first amplifier's input value is 0"
186+
phase_setting.push(0);
187+
}
188+
189+
return new Computer(memory, phase_setting, i);
190+
});
191+
192+
this.current_computer = 0;
165193
}
166194

167-
run(return_last_output = true) {
168-
// First computer gets 0 as its second input
169-
let last_computer_output = [0];
170-
for (let phase_seting of this.phase_settings) {
171-
let computer = new Computer(this.memory, [
172-
phase_seting,
173-
...last_computer_output,
174-
]);
175-
last_computer_output = computer.run();
195+
run() {
196+
let computer = this.circuit[this.current_computer];
197+
let output, last_output;
198+
199+
while (!computer.halted) {
200+
let new_output = computer.run();
201+
if (computer.halted) {
202+
break;
203+
}
204+
205+
output = new_output;
206+
207+
let next_computer = this.moveToNextComputer();
208+
209+
// `output.pop` removes the value from the computers `this.outputs` array,
210+
// meaning the next computer effectively "consumes" the value
211+
last_output = output.shift();
212+
next_computer.inputs.push(last_output);
213+
214+
computer = next_computer;
176215
}
177216

217+
return last_output;
218+
}
219+
220+
moveToNextComputer() {
221+
this.current_computer++;
222+
this.current_computer %= this.circuit.length;
178223

179-
return return_last_output ? last_computer_output.pop() : last_computer_output;
224+
return this.circuit[this.current_computer];
180225
}
181226
}
182227

2019/7/part-two.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
1+
const G = require('generatorics');
12
const { input } = require('./input');
2-
const Computer = require('./computer');
3+
const { Circuit } = require('./circuit');
4+
5+
let max_output = Number.MIN_SAFE_INTEGER;
6+
for (var phase_settings of G.permutation([9, 8, 7, 6, 5])) {
7+
let circuit = new Circuit(input, phase_settings);
8+
let output = circuit.run();
9+
if (output > max_output) {
10+
max_output = output;
11+
}
12+
}
13+
14+
console.log(max_output);

0 commit comments

Comments
 (0)