|
@@ -91,7 +91,7 @@ does the program produce?
|
|
|
|
|
|
|
|
use log::{debug, trace};
|
|
use log::{debug, trace};
|
|
|
use std::convert::TryFrom;
|
|
use std::convert::TryFrom;
|
|
|
-use std::io::{stdin, stdout, Write};
|
|
|
|
|
|
|
+use std::io::{stdin, stdout, BufRead, Write};
|
|
|
|
|
|
|
|
use crate::puzzle::options::Options;
|
|
use crate::puzzle::options::Options;
|
|
|
use crate::puzzle::traits::{Create, Solve};
|
|
use crate::puzzle::traits::{Create, Solve};
|
|
@@ -128,7 +128,7 @@ impl Create for Puzzle {
|
|
|
|
|
|
|
|
impl Puzzle {
|
|
impl Puzzle {
|
|
|
fn solve_p1(&self) -> i32 {
|
|
fn solve_p1(&self) -> i32 {
|
|
|
- let result = self.computer.run();
|
|
|
|
|
|
|
+ let result = self.computer.run(stdin().lock(), stdout());
|
|
|
match result {
|
|
match result {
|
|
|
Ok(res) => res[0],
|
|
Ok(res) => res[0],
|
|
|
Err(e) => panic!(e),
|
|
Err(e) => panic!(e),
|
|
@@ -311,7 +311,12 @@ impl Operation<'_> {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- fn apply(&mut self, index: usize) -> Result<Option<usize>, String> {
|
|
|
|
|
|
|
+ fn apply(
|
|
|
|
|
+ &mut self,
|
|
|
|
|
+ index: usize,
|
|
|
|
|
+ reader: &mut impl BufRead,
|
|
|
|
|
+ writer: &mut impl Write,
|
|
|
|
|
+ ) -> Result<Option<usize>, String> {
|
|
|
debug!("applying {:?} at index {}", self, index);
|
|
debug!("applying {:?} at index {}", self, index);
|
|
|
|
|
|
|
|
match &self.opcode {
|
|
match &self.opcode {
|
|
@@ -327,10 +332,10 @@ impl Operation<'_> {
|
|
|
}
|
|
}
|
|
|
OpCode::Input => {
|
|
OpCode::Input => {
|
|
|
print!("Input: ");
|
|
print!("Input: ");
|
|
|
- stdout().flush().unwrap();
|
|
|
|
|
|
|
+ writer.flush().unwrap();
|
|
|
|
|
|
|
|
let input = &mut String::new();
|
|
let input = &mut String::new();
|
|
|
- let _ = stdin().read_line(input);
|
|
|
|
|
|
|
+ let _ = reader.read_line(input);
|
|
|
let num: i32 = match input.trim().parse() {
|
|
let num: i32 = match input.trim().parse() {
|
|
|
Ok(x) => x,
|
|
Ok(x) => x,
|
|
|
Err(e) => return Err(format!("failed to decode input {}: {}", input, e)),
|
|
Err(e) => return Err(format!("failed to decode input {}: {}", input, e)),
|
|
@@ -339,7 +344,10 @@ impl Operation<'_> {
|
|
|
}
|
|
}
|
|
|
OpCode::Output => {
|
|
OpCode::Output => {
|
|
|
let arg1 = self.value_from(self.param_1_mode, index + 1);
|
|
let arg1 = self.value_from(self.param_1_mode, index + 1);
|
|
|
- println!("Output: {}", arg1);
|
|
|
|
|
|
|
+ match write!(writer, "Output: {}", arg1) {
|
|
|
|
|
+ Ok(_) => {}
|
|
|
|
|
+ Err(e) => return Err(format!("Error writing output {}: {}", arg1, e)),
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
OpCode::Halt => return Ok(None),
|
|
OpCode::Halt => return Ok(None),
|
|
|
}
|
|
}
|
|
@@ -396,7 +404,7 @@ struct Computer {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
impl Computer {
|
|
impl Computer {
|
|
|
- fn run(&self) -> Result<Vec<i32>, String> {
|
|
|
|
|
|
|
+ fn run(&self, mut reader: impl BufRead, mut writer: impl Write) -> Result<Vec<i32>, String> {
|
|
|
let mut index: usize = 0;
|
|
let mut index: usize = 0;
|
|
|
let ref mut opcodes = self.opcodes.clone();
|
|
let ref mut opcodes = self.opcodes.clone();
|
|
|
|
|
|
|
@@ -411,7 +419,7 @@ impl Computer {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- match op.apply(index) {
|
|
|
|
|
|
|
+ match op.apply(index, &mut reader, &mut writer) {
|
|
|
Ok(Some(i)) => index += i,
|
|
Ok(Some(i)) => index += i,
|
|
|
Ok(None) => break,
|
|
Ok(None) => break,
|
|
|
Err(e) => return Err(e),
|
|
Err(e) => return Err(e),
|
|
@@ -430,11 +438,14 @@ mod puzzle_1 {
|
|
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
|
fn opcodes_sample_1() {
|
|
fn opcodes_sample_1() {
|
|
|
|
|
+ let buf_reader = b"";
|
|
|
|
|
+ let mut writer = Vec::new();
|
|
|
|
|
+
|
|
|
assert_eq!(
|
|
assert_eq!(
|
|
|
Computer {
|
|
Computer {
|
|
|
opcodes: vec![1002, 4, 3, 4, 33],
|
|
opcodes: vec![1002, 4, 3, 4, 33],
|
|
|
}
|
|
}
|
|
|
- .run()
|
|
|
|
|
|
|
+ .run(&buf_reader[..], &mut writer)
|
|
|
.unwrap(),
|
|
.unwrap(),
|
|
|
vec![1002, 4, 3, 4, 99]
|
|
vec![1002, 4, 3, 4, 99]
|
|
|
);
|
|
);
|
|
@@ -442,11 +453,14 @@ mod puzzle_1 {
|
|
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
|
fn opcodes_sample_2() {
|
|
fn opcodes_sample_2() {
|
|
|
|
|
+ let buf_reader = b"";
|
|
|
|
|
+ let mut writer = Vec::new();
|
|
|
|
|
+
|
|
|
assert_eq!(
|
|
assert_eq!(
|
|
|
Computer {
|
|
Computer {
|
|
|
opcodes: vec![1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50]
|
|
opcodes: vec![1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50]
|
|
|
}
|
|
}
|
|
|
- .run()
|
|
|
|
|
|
|
+ .run(&buf_reader[..], &mut writer)
|
|
|
.unwrap(),
|
|
.unwrap(),
|
|
|
vec![3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50]
|
|
vec![3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50]
|
|
|
);
|
|
);
|
|
@@ -454,11 +468,14 @@ mod puzzle_1 {
|
|
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
|
fn opcodes_sample_3() {
|
|
fn opcodes_sample_3() {
|
|
|
|
|
+ let buf_reader = b"";
|
|
|
|
|
+ let mut writer = Vec::new();
|
|
|
|
|
+
|
|
|
assert_eq!(
|
|
assert_eq!(
|
|
|
Computer {
|
|
Computer {
|
|
|
opcodes: vec![10001, 1, 1, 0, 99]
|
|
opcodes: vec![10001, 1, 1, 0, 99]
|
|
|
}
|
|
}
|
|
|
- .run()
|
|
|
|
|
|
|
+ .run(&buf_reader[..], &mut writer)
|
|
|
.unwrap(),
|
|
.unwrap(),
|
|
|
vec![10001, 1, 1, 2, 99]
|
|
vec![10001, 1, 1, 2, 99]
|
|
|
);
|
|
);
|
|
@@ -466,11 +483,14 @@ mod puzzle_1 {
|
|
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
|
fn opcodes_sample_4() {
|
|
fn opcodes_sample_4() {
|
|
|
|
|
+ let buf_reader = b"";
|
|
|
|
|
+ let mut writer = Vec::new();
|
|
|
|
|
+
|
|
|
assert_eq!(
|
|
assert_eq!(
|
|
|
Computer {
|
|
Computer {
|
|
|
opcodes: vec![1, 0, 0, 0, 99]
|
|
opcodes: vec![1, 0, 0, 0, 99]
|
|
|
}
|
|
}
|
|
|
- .run()
|
|
|
|
|
|
|
+ .run(&buf_reader[..], &mut writer)
|
|
|
.unwrap(),
|
|
.unwrap(),
|
|
|
vec![2, 0, 0, 0, 99]
|
|
vec![2, 0, 0, 0, 99]
|
|
|
);
|
|
);
|
|
@@ -478,13 +498,19 @@ mod puzzle_1 {
|
|
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
|
fn opcodes_sample_5() {
|
|
fn opcodes_sample_5() {
|
|
|
|
|
+ let buf_reader = b"1234";
|
|
|
|
|
+ let mut writer = Vec::new();
|
|
|
|
|
+
|
|
|
assert_eq!(
|
|
assert_eq!(
|
|
|
Computer {
|
|
Computer {
|
|
|
opcodes: vec![3, 0, 4, 0, 99]
|
|
opcodes: vec![3, 0, 4, 0, 99]
|
|
|
}
|
|
}
|
|
|
- .run()
|
|
|
|
|
|
|
+ .run(&buf_reader[..], &mut writer)
|
|
|
.unwrap(),
|
|
.unwrap(),
|
|
|
- vec![2, 0, 0, 0, 99]
|
|
|
|
|
|
|
+ vec![1234, 0, 4, 0, 99]
|
|
|
);
|
|
);
|
|
|
|
|
+
|
|
|
|
|
+ let expected = b"Output: 1234";
|
|
|
|
|
+ assert_eq!(expected.to_vec(), writer)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|