1use crate::intcode::features::{Day05Part1Features, Day05Part2Features};
2use crate::intcode::{Event, Features, Interpreter};
3use utils::prelude::*;
4
5#[derive(Clone, Debug)]
7pub struct Day05 {
8 interpreter: Interpreter,
9}
10
11impl Day05 {
12 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
13 Ok(Self {
14 interpreter: Interpreter::parse(input, 1)?,
15 })
16 }
17
18 #[must_use]
19 pub fn part1(&self) -> i64 {
20 self.run::<Day05Part1Features>(1)
21 }
22
23 #[must_use]
24 pub fn part2(&self) -> i64 {
25 self.run::<Day05Part2Features>(5)
26 }
27
28 fn run<F: Features>(&self, input: i64) -> i64 {
29 let mut interpreter = self.interpreter.clone();
30 interpreter.push_input(input);
31
32 let mut last_output = 0;
33 loop {
34 match interpreter.run::<F>() {
35 Event::Halt if last_output != 0 => return last_output,
36 Event::Halt => panic!("no solution found: no non-zero output"),
37 Event::Input => panic!("no solution found: program requires more input"),
38 Event::Output(_) if last_output != 0 => {
39 panic!("no solution found: output after non-zero output")
40 }
41 Event::Output(x) => last_output = x,
42 }
43 }
44 }
45}
46
47examples!(Day05 -> (i64, i64) []);