year2019/
day05.rs

1use crate::intcode::features::{Day05Part1Features, Day05Part2Features};
2use crate::intcode::{Event, Features, Interpreter};
3use utils::prelude::*;
4
5/// Interpreting assembly with IO, conditionals and immediate operands.
6#[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) []);