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