mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-12-18 10:19:55 +00:00
Add computer module to support day 5
This commit is contained in:
parent
4f2c160b1b
commit
e657f6ec9f
3 changed files with 131 additions and 0 deletions
1
2019/input/day5.txt
Normal file
1
2019/input/day5.txt
Normal file
|
@ -0,0 +1 @@
|
|||
3,225,1,225,6,6,1100,1,238,225,104,0,1101,61,45,225,102,94,66,224,101,-3854,224,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,31,30,225,1102,39,44,224,1001,224,-1716,224,4,224,102,8,223,223,1001,224,7,224,1,224,223,223,1101,92,41,225,101,90,40,224,1001,224,-120,224,4,224,102,8,223,223,1001,224,1,224,1,223,224,223,1101,51,78,224,101,-129,224,224,4,224,1002,223,8,223,1001,224,6,224,1,224,223,223,1,170,13,224,101,-140,224,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,1101,14,58,225,1102,58,29,225,1102,68,70,225,1002,217,87,224,101,-783,224,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,1101,19,79,225,1001,135,42,224,1001,224,-56,224,4,224,102,8,223,223,1001,224,6,224,1,224,223,223,2,139,144,224,1001,224,-4060,224,4,224,102,8,223,223,101,1,224,224,1,223,224,223,1102,9,51,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,1008,677,226,224,102,2,223,223,1006,224,329,101,1,223,223,108,677,677,224,102,2,223,223,1005,224,344,101,1,223,223,107,677,677,224,1002,223,2,223,1005,224,359,101,1,223,223,1107,226,677,224,1002,223,2,223,1005,224,374,1001,223,1,223,1008,677,677,224,102,2,223,223,1006,224,389,1001,223,1,223,1007,677,677,224,1002,223,2,223,1006,224,404,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,419,1001,223,1,223,8,226,226,224,102,2,223,223,1006,224,434,101,1,223,223,1107,226,226,224,1002,223,2,223,1006,224,449,101,1,223,223,1107,677,226,224,102,2,223,223,1005,224,464,101,1,223,223,1108,226,226,224,102,2,223,223,1006,224,479,1001,223,1,223,7,677,677,224,1002,223,2,223,1006,224,494,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,509,101,1,223,223,1108,226,677,224,1002,223,2,223,1006,224,524,101,1,223,223,8,226,677,224,1002,223,2,223,1005,224,539,101,1,223,223,1007,226,226,224,102,2,223,223,1006,224,554,1001,223,1,223,108,226,226,224,1002,223,2,223,1006,224,569,1001,223,1,223,1108,677,226,224,102,2,223,223,1005,224,584,101,1,223,223,108,226,677,224,102,2,223,223,1005,224,599,101,1,223,223,1007,226,677,224,102,2,223,223,1006,224,614,1001,223,1,223,1008,226,226,224,1002,223,2,223,1006,224,629,1001,223,1,223,107,226,226,224,1002,223,2,223,1006,224,644,101,1,223,223,7,226,677,224,102,2,223,223,1005,224,659,1001,223,1,223,107,677,226,224,102,2,223,223,1005,224,674,1001,223,1,223,4,223,99,226
|
129
2019/src/computer.rs
Normal file
129
2019/src/computer.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
type Address = i32;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum Instruction {
|
||||
Add(Mode, Mode),
|
||||
Multiply(Mode, Mode),
|
||||
Input(Mode),
|
||||
Output(Mode),
|
||||
Halt,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum Mode {
|
||||
Immediate,
|
||||
Address,
|
||||
}
|
||||
|
||||
struct Memory<'a> {
|
||||
mem: &'a mut [i32],
|
||||
}
|
||||
|
||||
fn decode(mut instruction: i32) -> Instruction {
|
||||
let opcode = divmod(&mut instruction, 100);
|
||||
|
||||
match opcode {
|
||||
1 => {
|
||||
// let mode3 = divmod(&mut instruction, 10);
|
||||
// Parameters that an instruction writes to will never be in immediate mode.
|
||||
Instruction::Add(
|
||||
Mode::from(divmod(&mut instruction, 10)),
|
||||
Mode::from(divmod(&mut instruction, 10)),
|
||||
)
|
||||
}
|
||||
2 => Instruction::Multiply(
|
||||
Mode::from(divmod(&mut instruction, 10)),
|
||||
Mode::from(divmod(&mut instruction, 10)),
|
||||
),
|
||||
3 => Instruction::Input(Mode::from(divmod(&mut instruction, 10))),
|
||||
4 => Instruction::Output(Mode::from(divmod(&mut instruction, 10))),
|
||||
99 => Instruction::Halt,
|
||||
_ => panic!("Invalid opcode: {}", opcode),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Memory<'a> {
|
||||
pub fn new(mem: &'a mut [i32]) -> Self {
|
||||
Memory { mem }
|
||||
}
|
||||
|
||||
pub fn read(&self, value: i32, mode: Mode) -> i32 {
|
||||
match mode {
|
||||
Mode::Immediate => value,
|
||||
Mode::Address => self.mem[value as usize],
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&mut self, address: Address, value: i32) {
|
||||
self.mem[address as usize] = value;
|
||||
}
|
||||
|
||||
fn run(&mut self, noun: i32, verb: i32) {
|
||||
self.write(1, noun);
|
||||
self.write(2, verb);
|
||||
let mut ip = 0; // instruction pointer
|
||||
|
||||
loop {
|
||||
match decode(self.read(ip, Mode::Address)) {
|
||||
Instruction::Add(mode1, mode2) => {
|
||||
let result = self.read(ip + 1, mode1) + self.read(ip + 1, mode2);
|
||||
self.write(ip + 3, result);
|
||||
ip += 4;
|
||||
}
|
||||
Instruction::Multiply(mode1, mode2) => {
|
||||
let result = self.read(ip + 1, mode1) * self.read(ip + 1, mode2);
|
||||
self.write(ip + 3, result);
|
||||
ip += 4;
|
||||
}
|
||||
Instruction::Input(mode) => {
|
||||
ip += 2;
|
||||
}
|
||||
Instruction::Output(mode) => {
|
||||
ip += 2;
|
||||
}
|
||||
Instruction::Halt => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn divmod(value: &mut i32, divisor: i32) -> i32 {
|
||||
let res = *value % divisor;
|
||||
*value /= divisor;
|
||||
res
|
||||
}
|
||||
|
||||
impl From<i32> for Mode {
|
||||
fn from(mode: i32) -> Self {
|
||||
match mode {
|
||||
0 => Mode::Address,
|
||||
1 => Mode::Immediate,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::input;
|
||||
use std::fs;
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
assert_eq!(
|
||||
decode(1002),
|
||||
Instruction::Multiply(Mode::Address, Mode::Immediate)
|
||||
)
|
||||
}
|
||||
|
||||
fn test_day2() {
|
||||
let input = fs::read_to_string("input/day2.txt").unwrap();
|
||||
let mut data = input::read_separated_line(',', &input).unwrap();
|
||||
let mut program = Memory::new(&mut data);
|
||||
|
||||
// Check that day2 still works wirh run through this implementation
|
||||
program.run(12, 2);
|
||||
assert_eq!(program.read(0, Mode::Address), 4138658);
|
||||
}
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
pub mod computer;
|
||||
pub mod input;
|
||||
pub mod point;
|
||||
|
|
Loading…
Reference in a new issue