mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-12-18 18:29:55 +00:00
Make Computer do I/O in terms of traits
This commit is contained in:
parent
af694da6ce
commit
5965959a05
3 changed files with 42 additions and 16 deletions
|
@ -5,13 +5,13 @@ fn main() -> io::Result<()> {
|
||||||
let input = fs::read_to_string("input/day5.txt")?;
|
let input = fs::read_to_string("input/day5.txt")?;
|
||||||
let data = input::read_separated_line(',', &input)?;
|
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);
|
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);
|
computer.run(None, None);
|
||||||
println!("Part 2: {:?}", computer.output());
|
println!("Part 2: {}", computer.output());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,9 @@ fn part1(data: Vec<i32>) {
|
||||||
let mut output = 0;
|
let mut output = 0;
|
||||||
for phase_setting in settings.iter() {
|
for phase_setting in settings.iter() {
|
||||||
let input = vec![output, *phase_setting];
|
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);
|
computer.run(None, None);
|
||||||
output = computer.output()[0];
|
output = computer.output();
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,10 +19,36 @@ enum Mode {
|
||||||
Address,
|
Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Computer {
|
pub struct Computer<I: Input, O: Output> {
|
||||||
memory: Vec<i32>,
|
memory: Vec<i32>,
|
||||||
input: Vec<i32>,
|
input: I,
|
||||||
output: Vec<i32>,
|
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 {
|
fn decode(mut instruction: i32) -> Instruction {
|
||||||
|
@ -64,12 +90,12 @@ fn decode(mut instruction: i32) -> Instruction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Computer {
|
impl<I, O> Computer<I, O> where I: Input, O: Output {
|
||||||
pub fn new(memory: Vec<i32>, input: Vec<i32>) -> Self {
|
pub fn new(memory: Vec<i32>, input: I, output: O) -> Self {
|
||||||
Computer {
|
Computer {
|
||||||
memory,
|
memory,
|
||||||
input,
|
input,
|
||||||
output: vec![],
|
output,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,12 +132,12 @@ impl Computer {
|
||||||
ip += 4;
|
ip += 4;
|
||||||
}
|
}
|
||||||
Instruction::Input => {
|
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);
|
self.write(self.read(ip + 1, Mode::Immediate), value);
|
||||||
ip += 2;
|
ip += 2;
|
||||||
}
|
}
|
||||||
Instruction::Output(mode) => {
|
Instruction::Output(mode) => {
|
||||||
self.output.push(self.read(ip + 1, mode));
|
self.output.write(self.read(ip + 1, mode));
|
||||||
ip += 2;
|
ip += 2;
|
||||||
}
|
}
|
||||||
Instruction::JumpIfTrue(mode1, mode2) => {
|
Instruction::JumpIfTrue(mode1, mode2) => {
|
||||||
|
@ -149,8 +175,8 @@ impl Computer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn output(&self) -> &[i32] {
|
pub fn output(&self) -> i32 {
|
||||||
&self.output
|
self.output.last_value()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue