Make Computer do I/O in terms of traits

This commit is contained in:
Wesley Moore 2019-12-08 10:07:15 +11:00
parent af694da6ce
commit 5965959a05
No known key found for this signature in database
GPG key ID: BF67766C0BC2D0EE
3 changed files with 42 additions and 16 deletions

View file

@ -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(())
}

View file

@ -25,9 +25,9 @@ fn part1(data: Vec<i32>) {
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
})

View file

@ -19,10 +19,36 @@ enum Mode {
Address,
}
pub struct Computer {
pub struct Computer<I: Input, O: Output> {
memory: Vec<i32>,
input: Vec<i32>,
output: Vec<i32>,
input: I,
output: O,
}
pub trait Input {
fn read(&mut self) -> Option<i32>;
}
pub trait Output {
fn write(&mut self, value: i32);
fn last_value(&self) -> i32;
}
impl Input for Vec<i32> {
fn read(&mut self) -> Option<i32> {
self.pop()
}
}
impl Output for Vec<i32> {
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<i32>, input: Vec<i32>) -> Self {
impl<I, O> Computer<I, O> where I: Input, O: Output {
pub fn new(memory: Vec<i32>, 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()
}
}