diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2019-12-11 00:23:51 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2019-12-11 00:23:51 +0200 |
commit | 9438066faf52464f8834035721733d82cdf4e322 (patch) | |
tree | ddfdb260a9c39ca4c6f461b5bf22eee7c7780669 /src/bin/day_5.rs | |
parent | 955de25778eb7e93e7872dfafbc9569cb345e920 (diff) |
Cleaned up error handling
It still doesn't say anything about the errors, but maybe next time.
Diffstat (limited to 'src/bin/day_5.rs')
-rw-r--r-- | src/bin/day_5.rs | 138 |
1 files changed, 72 insertions, 66 deletions
diff --git a/src/bin/day_5.rs b/src/bin/day_5.rs index a6de781..e7539e1 100644 --- a/src/bin/day_5.rs +++ b/src/bin/day_5.rs @@ -56,10 +56,10 @@ fn exit_on_failed_assertion<A, E: std::error::Error>(data: Result<A, E>, message #[derive(Debug, Clone)] struct Program { - program_counter: usize, + instruction_pointer: usize, error: bool, halted: bool, - codes: Vector<Intcode>, + memory: Vector<Intcode>, input: List<Intcode>, output: Vector<Intcode>, } @@ -67,10 +67,10 @@ struct Program { impl FromIterator<Intcode> for Program { fn from_iter<I: IntoIterator<Item = Intcode>>(iter: I) -> Self { Program { - program_counter: 0, + instruction_pointer: 0, error: false, halted: false, - codes: iter.into_iter().collect(), + memory: iter.into_iter().collect(), input: List::new(), output: Vector::new(), } @@ -85,6 +85,47 @@ impl Program { } } + fn with_instruction_pointer(&self, instruction_pointer: usize) -> Program { + Program { + instruction_pointer, + ..self.clone() + } + } + + fn with_instruction_pointer_offset(&self, offset: usize) -> Program { + Program { + instruction_pointer: self.instruction_pointer + offset, + ..self.clone() + } + } + + fn with_memory_set(&self, address: usize, value: Intcode) -> Program { + self.memory + .set(address, value) + .map(|memory| Program { + memory, + ..self.clone() + }) + .unwrap_or(self.error()) + } + + fn with_input_consumed(&self) -> Program { + self.input + .drop_first() + .map(|input| Program { + input, + ..self.clone() + }) + .unwrap_or(self.error()) + } + + fn with_output(&self, print: Intcode) -> Program { + Program { + output: self.output.push_back(print), + ..self.clone() + } + } + fn execute(&self) -> Result<Vector<Intcode>, ProgramError> { self.run_to_termination().into_result() } @@ -105,8 +146,8 @@ impl Program { fn next(&self) -> Program { //eprintln!("{:?}", self); - self.codes - .get(self.program_counter) + self.memory + .get(self.instruction_pointer) .map(|&opcode| match opcode % 100 { 1 => self.add(opcode), 2 => self.multiply(opcode), @@ -124,103 +165,68 @@ impl Program { fn add(&self, mode: Intcode) -> Program { match (self.get(1, mode), self.get(2, mode), self.get_immediate(3)) { - (Some(in1), Some(in2), Some(out)) => Program { - program_counter: self.program_counter + 4, - codes: self.codes.set(out as usize, in1 + in2).unwrap(), - ..self.clone() - }, + (Some(in1), Some(in2), Some(out)) => self + .with_instruction_pointer_offset(4) + .with_memory_set(out as usize, in1 + in2), _ => self.error(), } } fn multiply(&self, mode: Intcode) -> Program { match (self.get(1, mode), self.get(2, mode), self.get_immediate(3)) { - (Some(in1), Some(in2), Some(out)) => Program { - program_counter: self.program_counter + 4, - codes: self.codes.set(out as usize, in1 * in2).unwrap(), - ..self.clone() - }, + (Some(in1), Some(in2), Some(out)) => self + .with_instruction_pointer_offset(4) + .with_memory_set(out as usize, in1 * in2), _ => self.error(), } } fn input(&self, _mode: Intcode) -> Program { - match self.get_immediate(1) { - Some(out) => Program { - program_counter: self.program_counter + 2, - codes: self - .codes - .set(out as usize, *self.input.first().unwrap()) - .unwrap(), - input: self.input.drop_first().unwrap(), - ..self.clone() - }, + match (self.input.first().cloned(), self.get_immediate(1)) { + (Some(input), Some(out)) => self + .with_instruction_pointer_offset(2) + .with_memory_set(out as usize, input) + .with_input_consumed(), _ => self.error(), } } fn output(&self, mode: Intcode) -> Program { match self.get(1, mode) { - Some(print) => Program { - program_counter: self.program_counter + 2, - output: self.output.push_back(print), - ..self.clone() - }, + Some(print) => self.with_instruction_pointer_offset(2).with_output(print), _ => self.error(), } } fn jump_if_true(&self, mode: Intcode) -> Program { match (self.get(1, mode), self.get(2, mode)) { - (Some(pred), Some(to)) => Program { - program_counter: if pred != 0 { - to as usize - } else { - self.program_counter + 3 - }, - ..self.clone() - }, + (Some(pred), Some(to)) if pred != 0 => self.with_instruction_pointer(to as usize), + (Some(_), Some(_)) => self.with_instruction_pointer_offset(3), _ => self.error(), } } fn jump_if_false(&self, mode: Intcode) -> Program { match (self.get(1, mode), self.get(2, mode)) { - (Some(pred), Some(to)) => Program { - program_counter: if pred == 0 { - to as usize - } else { - self.program_counter + 3 - }, - ..self.clone() - }, + (Some(pred), Some(to)) if pred == 0 => self.with_instruction_pointer(to as usize), + (Some(_), Some(_)) => self.with_instruction_pointer_offset(3), _ => self.error(), } } fn less_than(&self, mode: Intcode) -> Program { match (self.get(1, mode), self.get(2, mode), self.get_immediate(3)) { - (Some(in1), Some(in2), Some(out)) => Program { - program_counter: self.program_counter + 4, - codes: self - .codes - .set(out as usize, if in1 < in2 { 1 } else { 0 }) - .unwrap(), - ..self.clone() - }, + (Some(in1), Some(in2), Some(out)) => self + .with_instruction_pointer_offset(4) + .with_memory_set(out as usize, if in1 < in2 { 1 } else { 0 }), _ => self.error(), } } fn equals(&self, mode: Intcode) -> Program { match (self.get(1, mode), self.get(2, mode), self.get_immediate(3)) { - (Some(in1), Some(in2), Some(out)) => Program { - program_counter: self.program_counter + 4, - codes: self - .codes - .set(out as usize, if in1 == in2 { 1 } else { 0 }) - .unwrap(), - ..self.clone() - }, + (Some(in1), Some(in2), Some(out)) => self + .with_instruction_pointer_offset(4) + .with_memory_set(out as usize, if in1 == in2 { 1 } else { 0 }), _ => self.error(), } } @@ -249,14 +255,14 @@ impl Program { } fn get_immediate(&self, pointer_offset: usize) -> Option<Intcode> { - self.codes - .get(self.program_counter + pointer_offset) + self.memory + .get(self.instruction_pointer + pointer_offset) .cloned() } fn get_position(&self, pointer_offset: usize) -> Option<Intcode> { self.get_immediate(pointer_offset) - .and_then(|r| self.codes.get(r as usize)) + .and_then(|r| self.memory.get(r as usize)) .cloned() } } |