aoc/year2019/
day07.rs

1//! # Amplification Circuit
2//!
3//! Brute force solution for both parts using the utility [`permutations`] method to test each of
4//! the possible 5! or 120 permutations of the phase settings.
5//!
6//! [`permutations`]: crate::util::slice
7use super::intcode::*;
8use crate::util::parse::*;
9use crate::util::slice::*;
10use std::array::from_fn;
11
12pub fn parse(input: &str) -> Vec<i64> {
13    input.iter_signed::<i64>().collect()
14}
15
16pub fn part1(input: &[i64]) -> i64 {
17    let mut result = 0;
18    let mut computer = Computer::new(input);
19
20    let sequence = |slice: &[i64]| {
21        let mut signal = 0;
22
23        // Send exactly 2 inputs and receive exactly 1 output per amplifier.
24        for &phase in slice {
25            computer.reset();
26            computer.input(phase);
27            computer.input(signal);
28            let State::Output(next) = computer.run() else { unreachable!() };
29            signal = next;
30        }
31
32        result = result.max(signal);
33    };
34
35    [0, 1, 2, 3, 4].permutations(sequence);
36    result
37}
38
39pub fn part2(input: &[i64]) -> i64 {
40    let mut result = 0;
41    let mut computers: [Computer; 5] = from_fn(|_| Computer::new(input));
42
43    let feedback = |slice: &[i64]| {
44        // Reset state.
45        computers.iter_mut().for_each(Computer::reset);
46
47        // Send each initial phase setting exactly once.
48        for (computer, &phase) in computers.iter_mut().zip(slice) {
49            computer.input(phase);
50        }
51
52        // Chain amplifier inputs and outputs in a loop until all threads finish.
53        let mut signal = 0;
54
55        'outer: loop {
56            for computer in &mut computers {
57                computer.input(signal);
58                let State::Output(next) = computer.run() else { break 'outer };
59                signal = next;
60            }
61        }
62
63        result = result.max(signal);
64    };
65
66    [5, 6, 7, 8, 9].permutations(feedback);
67    result
68}