diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 62 |
1 files changed, 51 insertions, 11 deletions
@@ -9,11 +9,12 @@ pub type Intcode = i32; #[derive(Debug, Clone)] pub struct IntcodeProgram { instruction_pointer: usize, - error: bool, - halted: bool, + pub error: bool, + pub halted: bool, + pub awaiting_input: bool, memory: Vector<Intcode>, - input: List<Intcode>, - output: Vector<Intcode>, + pub input: List<Intcode>, + pub output: Vector<Intcode>, } impl FromIterator<Intcode> for IntcodeProgram { @@ -22,6 +23,7 @@ impl FromIterator<Intcode> for IntcodeProgram { instruction_pointer: 0, error: false, halted: false, + awaiting_input: false, memory: iter.into_iter().collect(), input: List::new(), output: Vector::new(), @@ -41,6 +43,20 @@ impl IntcodeProgram { } } + pub fn with_additional_input(&self, input: List<Intcode>) -> IntcodeProgram { + IntcodeProgram { + input: self.input.iter().chain(input.iter()).cloned().collect(), + ..self.clone() + } + } + + pub fn with_cleared_output(&self) -> IntcodeProgram { + IntcodeProgram { + output: Vector::new(), + ..self.clone() + } + } + pub fn execute(&self) -> Result<Vector<Intcode>, IntcodeProgramError> { self.run_to_termination().output_into_result() } @@ -49,6 +65,22 @@ impl IntcodeProgram { self.run_to_termination().memory_0_into_result() } + pub fn run_to_termination(&self) -> IntcodeProgram { + iter::successors(Some(self.clear_await_input()), |p| { + Some(IntcodeProgram::next(&p)) + }) + .find(|p| p.halted) + .unwrap() // successors doesn't terminate, so this will never be none. + } + + pub fn run_to_termination_or_input(&self) -> IntcodeProgram { + iter::successors(Some(self.clear_await_input()), |p| { + Some(IntcodeProgram::next(&p)) + }) + .find(|p| p.halted || p.awaiting_input) + .unwrap() + } + fn with_instruction_pointer(&self, instruction_pointer: usize) -> IntcodeProgram { IntcodeProgram { instruction_pointer, @@ -105,13 +137,6 @@ impl IntcodeProgram { Ok(self.memory.get(0).cloned()) } } - - fn run_to_termination(&self) -> IntcodeProgram { - iter::successors(Some(self.clone()), |p| Some(IntcodeProgram::next(&p))) - .find(|p| p.halted) - .unwrap() // successors doesn't terminate, so this will never be none. - } - fn next(&self) -> IntcodeProgram { //eprintln!("{:?}", self); self.memory @@ -155,6 +180,7 @@ impl IntcodeProgram { .with_instruction_pointer_offset(2) .with_memory_set(out as usize, input) .with_input_consumed(), + (None, Some(_out)) => self.await_input(), _ => self.error(), } } @@ -206,6 +232,20 @@ impl IntcodeProgram { } } + fn await_input(&self) -> IntcodeProgram { + IntcodeProgram { + awaiting_input: true, + ..self.clone() + } + } + + fn clear_await_input(&self) -> IntcodeProgram { + IntcodeProgram { + awaiting_input: false, + ..self.clone() + } + } + fn error(&self) -> IntcodeProgram { IntcodeProgram { halted: true, |