From 5965959a058767ad280b9a62a14968ecde1d5d6e Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Sun, 8 Dec 2019 10:07:15 +1100 Subject: [PATCH] Make Computer do I/O in terms of traits --- 2019/src/bin/day5.rs | 8 ++++---- 2019/src/bin/day7.rs | 4 ++-- 2019/src/computer.rs | 46 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/2019/src/bin/day5.rs b/2019/src/bin/day5.rs index b7b92b2..3fd226c 100644 --- a/2019/src/bin/day5.rs +++ b/2019/src/bin/day5.rs @@ -5,13 +5,13 @@ fn main() -> io::Result<()> { let input = fs::read_to_string("input/day5.txt")?; let data = input::read_separated_line(',', &input)?; - let mut computer = computer::Computer::new(data.clone(), vec![1]); + let mut computer = computer::Computer::new(data.clone(), vec![1], vec![]); computer.run(None, None); - println!("Part 1: {:?}", computer.output()); + println!("Part 1: {}", computer.output()); - let mut computer = computer::Computer::new(data.clone(), vec![5]); + let mut computer = computer::Computer::new(data.clone(), vec![5], vec![]); computer.run(None, None); - println!("Part 2: {:?}", computer.output()); + println!("Part 2: {}", computer.output()); Ok(()) } diff --git a/2019/src/bin/day7.rs b/2019/src/bin/day7.rs index bcaee3f..e84c1a8 100644 --- a/2019/src/bin/day7.rs +++ b/2019/src/bin/day7.rs @@ -25,9 +25,9 @@ fn part1(data: Vec) { let mut output = 0; for phase_setting in settings.iter() { let input = vec![output, *phase_setting]; - let mut computer = computer::Computer::new(data.clone(), input); + let mut computer = computer::Computer::new(data.clone(), input, vec![]); computer.run(None, None); - output = computer.output()[0]; + output = computer.output(); } output }) diff --git a/2019/src/computer.rs b/2019/src/computer.rs index 91caf90..ff0c911 100644 --- a/2019/src/computer.rs +++ b/2019/src/computer.rs @@ -19,10 +19,36 @@ enum Mode { Address, } -pub struct Computer { +pub struct Computer { memory: Vec, - input: Vec, - output: Vec, + input: I, + output: O, +} + +pub trait Input { + fn read(&mut self) -> Option; +} + +pub trait Output { + fn write(&mut self, value: i32); + + fn last_value(&self) -> i32; +} + +impl Input for Vec { + fn read(&mut self) -> Option { + self.pop() + } +} + +impl Output for Vec { + fn write(&mut self, value: i32) { + self.push(value) + } + + fn last_value(&self) -> i32 { + *self.last().unwrap() + } } fn decode(mut instruction: i32) -> Instruction { @@ -64,12 +90,12 @@ fn decode(mut instruction: i32) -> Instruction { } } -impl Computer { - pub fn new(memory: Vec, input: Vec) -> Self { +impl Computer where I: Input, O: Output { + pub fn new(memory: Vec, input: I, output: O) -> Self { Computer { memory, input, - output: vec![], + output, } } @@ -106,12 +132,12 @@ impl Computer { ip += 4; } Instruction::Input => { - let value = self.input.pop().expect("no more input"); + let value = self.input.read().expect("no more input"); self.write(self.read(ip + 1, Mode::Immediate), value); ip += 2; } Instruction::Output(mode) => { - self.output.push(self.read(ip + 1, mode)); + self.output.write(self.read(ip + 1, mode)); ip += 2; } Instruction::JumpIfTrue(mode1, mode2) => { @@ -149,8 +175,8 @@ impl Computer { } } - pub fn output(&self) -> &[i32] { - &self.output + pub fn output(&self) -> i32 { + self.output.last_value() } }