summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2019-12-11 00:23:51 +0200
committerJustin Wernick <justin@worthe-it.co.za>2019-12-11 00:23:51 +0200
commit9438066faf52464f8834035721733d82cdf4e322 (patch)
treeddfdb260a9c39ca4c6f461b5bf22eee7c7780669 /src
parent955de25778eb7e93e7872dfafbc9569cb345e920 (diff)
Cleaned up error handling
It still doesn't say anything about the errors, but maybe next time.
Diffstat (limited to 'src')
-rw-r--r--src/bin/day_5.rs138
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()
}
}