1use crate::intcode::features::Day05Part2Features;
2use crate::intcode::Interpreter;
3use std::ops::Range;
4use utils::prelude::*;
5
6#[derive(Clone, Debug)]
8pub struct Day07 {
9 interpreter: Interpreter,
10}
11
12impl Day07 {
13 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
14 Ok(Self {
15 interpreter: Interpreter::parse(input, 1)?,
16 })
17 }
18
19 #[must_use]
20 pub fn part1(&self) -> i64 {
21 let mut amplifier = self.interpreter.clone();
22 Self::best_signal(0..5, |phases| {
23 let mut signal = 0;
24 for phase in phases {
25 amplifier.clone_from(&self.interpreter);
26 amplifier.push_input(phase);
27 amplifier.push_input(signal);
28 signal = amplifier.expect_output::<Day05Part2Features>();
29 }
30 signal
31 })
32 }
33
34 #[must_use]
35 pub fn part2(&self) -> i64 {
36 let mut amplifiers: [Interpreter; 5] = std::array::from_fn(|_| self.interpreter.clone());
37 Self::best_signal(5..10, |phases| {
38 for (amplifier, &phase) in amplifiers.iter_mut().zip(&phases) {
39 amplifier.clone_from(&self.interpreter);
40 amplifier.push_input(phase);
41 }
42
43 let mut signal = 0;
44 loop {
45 for amplifier in &mut amplifiers {
46 amplifier.push_input(signal);
47 let Some(output) = amplifier.next_output::<Day05Part2Features>() else {
48 return signal;
49 };
50 signal = output;
51 }
52 }
53 })
54 }
55
56 #[inline]
57 fn best_signal(phases: Range<i64>, mut f: impl FnMut([i64; 5]) -> i64) -> i64 {
58 let mut best = i64::MIN;
59 for a in phases.start..phases.end {
60 for b in phases.start..phases.end {
61 if b == a {
62 continue;
63 }
64 for c in phases.start..phases.end {
65 if c == a || c == b {
66 continue;
67 }
68 for d in phases.start..phases.end {
69 if d == a || d == b || d == c {
70 continue;
71 }
72 for e in phases.start..phases.end {
73 if e == a || e == b || e == c || e == d {
74 continue;
75 }
76 best = best.max(f([a, b, c, d, e]));
77 }
78 }
79 }
80 }
81 }
82 best
83 }
84}
85
86examples!(Day07 -> (i64, i64) [
87 {
88 input: "3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0",
89 part1: 43210,
90 },
91 {
92 input: "3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0",
93 part1: 54321,
94 },
95 {
96 input: "3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0",
97 part1: 65210,
98 },
99 {
100 input: "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",
101 part2: 139629729,
102 },
103 {
104 input: "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",
105 part2: 18216,
106 },
107]);