Day 5, Part 1
This commit is contained in:
1
inputs/day5
Normal file
1
inputs/day5
Normal file
@@ -0,0 +1 @@
|
||||
3,225,1,225,6,6,1100,1,238,225,104,0,1001,210,88,224,101,-143,224,224,4,224,1002,223,8,223,101,3,224,224,1,223,224,223,101,42,92,224,101,-78,224,224,4,224,1002,223,8,223,1001,224,3,224,1,223,224,223,1101,73,10,225,1102,38,21,225,1102,62,32,225,1,218,61,224,1001,224,-132,224,4,224,102,8,223,223,1001,224,5,224,1,224,223,223,1102,19,36,225,102,79,65,224,101,-4898,224,224,4,224,102,8,223,223,101,4,224,224,1,224,223,223,1101,66,56,224,1001,224,-122,224,4,224,102,8,223,223,1001,224,2,224,1,224,223,223,1002,58,82,224,101,-820,224,224,4,224,1002,223,8,223,101,3,224,224,1,223,224,223,2,206,214,224,1001,224,-648,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,1102,76,56,224,1001,224,-4256,224,4,224,102,8,223,223,1001,224,6,224,1,223,224,223,1102,37,8,225,1101,82,55,225,1102,76,81,225,1101,10,94,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,8,226,677,224,102,2,223,223,1005,224,329,101,1,223,223,1008,677,677,224,1002,223,2,223,1006,224,344,1001,223,1,223,107,226,677,224,102,2,223,223,1005,224,359,1001,223,1,223,1108,677,677,224,1002,223,2,223,1006,224,374,101,1,223,223,1107,677,677,224,1002,223,2,223,1006,224,389,101,1,223,223,108,226,677,224,102,2,223,223,1006,224,404,101,1,223,223,7,677,677,224,102,2,223,223,1006,224,419,101,1,223,223,108,677,677,224,102,2,223,223,1006,224,434,1001,223,1,223,7,226,677,224,102,2,223,223,1006,224,449,1001,223,1,223,108,226,226,224,102,2,223,223,1005,224,464,101,1,223,223,8,226,226,224,1002,223,2,223,1006,224,479,101,1,223,223,1008,226,226,224,102,2,223,223,1005,224,494,1001,223,1,223,1008,677,226,224,1002,223,2,223,1005,224,509,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,524,101,1,223,223,1007,677,226,224,1002,223,2,223,1006,224,539,1001,223,1,223,1108,677,226,224,102,2,223,223,1005,224,554,1001,223,1,223,8,677,226,224,1002,223,2,223,1005,224,569,101,1,223,223,1108,226,677,224,1002,223,2,223,1005,224,584,101,1,223,223,1107,677,226,224,102,2,223,223,1006,224,599,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,614,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,629,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,644,101,1,223,223,1007,677,677,224,102,2,223,223,1006,224,659,1001,223,1,223,1007,226,226,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226
|
||||
117
src/machine.rs
117
src/machine.rs
@@ -1,41 +1,40 @@
|
||||
use std::fs;
|
||||
use std::iter::FromIterator;
|
||||
use std::str;
|
||||
use std::sync::mpsc::{Sender, Receiver};
|
||||
|
||||
const ADD: u64 = 1;
|
||||
const MULTIPLY: u64 = 2;
|
||||
const HALT: u64 = 99;
|
||||
const ADD: i64 = 1;
|
||||
const MULTIPLY: i64 = 2;
|
||||
const INPUT: i64 = 3;
|
||||
const OUTPUT: i64 = 4;
|
||||
const HALT: i64 = 99;
|
||||
|
||||
const MODE_POSITION: i64 = 0;
|
||||
const MODE_IMMEDIATE: i64 = 1;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Computer {
|
||||
memory: Vec<u64>,
|
||||
memory: Vec<i64>,
|
||||
position: usize
|
||||
}
|
||||
|
||||
impl Computer {
|
||||
pub fn load(path: &str, position: usize) -> Computer {
|
||||
let mut memory = vec![];
|
||||
let byte_buffer = fs::read(path).unwrap();
|
||||
let char_buffer = str::from_utf8(&byte_buffer).unwrap();
|
||||
Computer::from_string(&char_buffer, position)
|
||||
}
|
||||
|
||||
let mut current = 0;
|
||||
for c in char_buffer.chars() {
|
||||
match c {
|
||||
',' => {
|
||||
memory.push(current);
|
||||
current = 0;
|
||||
fn from_string(char_buffer: &str, position: usize) -> Computer {
|
||||
let mut memory = vec![];
|
||||
let mut char_iter = char_buffer.chars().peekable();
|
||||
|
||||
while char_iter.peek().is_some() {
|
||||
let next_iter = char_iter.by_ref().take_while(|x| *x != ',');
|
||||
let next_str = String::from_iter(next_iter);
|
||||
let next = i64::from_str_radix(&next_str.trim(), 10).unwrap();
|
||||
memory.push(next);
|
||||
}
|
||||
_ if c.is_digit(10) => {
|
||||
let val = c.to_digit(10).unwrap() as u64;
|
||||
current = (current * 10) + val;
|
||||
}
|
||||
_ if c.is_whitespace() => {
|
||||
}
|
||||
_ => {
|
||||
panic!("Unrecognized character: '{}'", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
memory.push(current);
|
||||
|
||||
Computer{ memory, position }
|
||||
}
|
||||
@@ -47,32 +46,57 @@ impl Computer {
|
||||
println!("POSITION: {}", self.position);
|
||||
}
|
||||
|
||||
pub fn read(&self, idx: usize) -> u64 {
|
||||
pub fn read(&self, idx: usize) -> i64 {
|
||||
self.memory[idx]
|
||||
}
|
||||
|
||||
pub fn write(&mut self, idx: usize, val: u64) {
|
||||
pub fn read_arg(&self, mode: i64, val: usize) -> i64 {
|
||||
match mode {
|
||||
MODE_POSITION => self.read(self.read(val) as usize),
|
||||
MODE_IMMEDIATE => self.read(val),
|
||||
_ => panic!("Unknown argument mode: {}", mode)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&mut self, idx: usize, val: i64) {
|
||||
self.memory[idx] = val;
|
||||
}
|
||||
|
||||
fn step(&mut self) {
|
||||
match self.read(self.position) {
|
||||
fn step(&mut self, input: &Receiver<i64>, output: &Sender<i64>) {
|
||||
let next_instruction = self.read(self.position);
|
||||
let opcode = next_instruction % 100;
|
||||
let arg1mode = (next_instruction / 100) % 10;
|
||||
let arg2mode = (next_instruction / 1000) % 10;
|
||||
let _arg3mode = (next_instruction / 10000) % 10;
|
||||
|
||||
match opcode {
|
||||
ADD => {
|
||||
let arg1 = self.read(self.position + 1) as usize;
|
||||
let arg2 = self.read(self.position + 2) as usize;
|
||||
let arg1 = self.read_arg(arg1mode, self.position + 1);
|
||||
let arg2 = self.read_arg(arg2mode, self.position + 2);
|
||||
let dest = self.read(self.position + 3) as usize;
|
||||
|
||||
self.write(dest, self.read(arg1) + self.read(arg2));
|
||||
self.write(dest, arg1 + arg2);
|
||||
self.position += 4;
|
||||
}
|
||||
MULTIPLY => {
|
||||
let arg1 = self.read(self.position + 1) as usize;
|
||||
let arg2 = self.read(self.position + 2) as usize;
|
||||
let arg1 = self.read_arg(arg1mode, self.position + 1);
|
||||
let arg2 = self.read_arg(arg2mode, self.position + 2);
|
||||
let dest = self.read(self.position + 3) as usize;
|
||||
|
||||
self.write(dest, self.read(arg1) * self.read(arg2));
|
||||
self.write(dest, arg1 * arg2);
|
||||
self.position += 4;
|
||||
}
|
||||
INPUT => {
|
||||
let dest = self.read(self.position + 1) as usize;
|
||||
let val = input.recv().expect("Failed to read input value from channel.");
|
||||
self.write(dest, val);
|
||||
self.position += 2;
|
||||
}
|
||||
OUTPUT => {
|
||||
let arg1 = self.read_arg(arg1mode, self.position + 1);
|
||||
output.send(arg1).expect("Send failed.");
|
||||
self.position += 2;
|
||||
}
|
||||
HALT => {}
|
||||
/* */
|
||||
unknown_pos =>
|
||||
@@ -84,36 +108,51 @@ impl Computer {
|
||||
self.read(self.position) == HALT
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
pub fn run(&mut self, input: &Receiver<i64>, output: &Sender<i64>) {
|
||||
while !self.halted() {
|
||||
self.step();
|
||||
self.step(input, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
use std::sync::mpsc::channel;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
let (deadsend, deadrecv) = channel();
|
||||
|
||||
let mut example1 = Computer{ memory: vec![1,0,0,0,99], position: 0 };
|
||||
let answer1 = Computer{ memory: vec![2,0,0,0,99], position: 4 };
|
||||
example1.step();
|
||||
example1.step(&deadrecv, &deadsend);
|
||||
assert_eq!(example1, answer1);
|
||||
assert!(example1.halted());
|
||||
|
||||
let mut example2 = Computer{ memory: vec![2,3,0,3,99], position: 0 };
|
||||
let answer2 = Computer{ memory: vec![2,3,0,6,99], position: 4 };
|
||||
example2.step();
|
||||
example2.step(&deadrecv, &deadsend);
|
||||
assert_eq!(example2, answer2);
|
||||
assert!(example2.halted());
|
||||
|
||||
let mut example3 = Computer{ memory: vec![2,4,4,5,99,0], position: 0 };
|
||||
let answer3 = Computer{ memory: vec![2,4,4,5,99,9801], position: 4 };
|
||||
example3.step();
|
||||
example3.step(&deadrecv, &deadsend);
|
||||
assert_eq!(example3, answer3);
|
||||
assert!(example3.halted());
|
||||
|
||||
let mut example4 = Computer{ memory: vec![1,1,1,4,99,5,6,0,99], position: 0 };
|
||||
let answer4 = Computer{ memory: vec![30,1,1,4,2,5,6,0,99], position: 8 };
|
||||
example4.run();
|
||||
example4.run(&deadrecv, &deadsend);
|
||||
assert_eq!(example4, answer4);
|
||||
assert!(example4.halted());
|
||||
|
||||
let mut example5 = Computer{ memory: vec![1002,4,3,4,33], position: 0 };
|
||||
let answer5 = Computer{ memory: vec![1002,4,3,4,99], position: 4 };
|
||||
example5.run(&deadrecv, &deadsend);
|
||||
assert_eq!(example5, answer5);
|
||||
|
||||
let mut example6 = Computer::from_string("1101,100,-1,4,0", 0);
|
||||
let answer6 = Computer{ memory: vec![1101,100,-1,4,99], position: 4 };
|
||||
example6.run(&deadrecv, &deadsend);
|
||||
assert_eq!(example6, answer6);
|
||||
}
|
||||
25
src/main.rs
25
src/main.rs
@@ -7,6 +7,7 @@ use crate::args::Command;
|
||||
use crate::fuel::calculate_fuel;
|
||||
use crate::wiremap::WireMap;
|
||||
use std::cmp::{max,min};
|
||||
use std::sync::mpsc::channel;
|
||||
|
||||
fn main() {
|
||||
match Command::get() {
|
||||
@@ -22,23 +23,17 @@ fn main() {
|
||||
println!("TOTAL FUEL: {}", total);
|
||||
}
|
||||
|
||||
Command::RunComputer(initial) => {
|
||||
Command::RunComputer(mut initial) => {
|
||||
let (my_sender, their_receiver) = channel();
|
||||
let (their_sender, my_receiver) = channel();
|
||||
println!("Initial Computer:");
|
||||
initial.show();
|
||||
println!("Searching ...");
|
||||
for noun in 0..99 {
|
||||
for verb in 0..99 {
|
||||
let mut proposed = initial.clone();
|
||||
proposed.write(1, noun);
|
||||
proposed.write(2, verb);
|
||||
proposed.run();
|
||||
if proposed.read(0) == 19690720 {
|
||||
println!("Noun: {}", noun);
|
||||
println!("Verb: {}", verb);
|
||||
println!("ANSWER: {}", 100 * noun + verb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("Running, with input 1.");
|
||||
my_sender.send(1).expect("Initial send failed");
|
||||
initial.run(&their_receiver, &their_sender);
|
||||
let result = my_receiver.recv().expect("Didn't get initial result");
|
||||
for val in my_receiver.iter() {
|
||||
println!("Received value: {}", val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user