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;
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]| {
computers.iter_mut().for_each(Computer::reset);
for (computer, &phase) in computers.iter_mut().zip(slice.iter()) {
computer.input(phase);
}
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
}