Skip to content

Commit

Permalink
2019: Day 5
Browse files Browse the repository at this point in the history
  • Loading branch information
ericvw committed Mar 14, 2024
1 parent db6a729 commit 6dd5bf5
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 21 deletions.
1 change: 1 addition & 0 deletions 2019/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ $(outputdir)/puzzle_%: $(srcbindir)/puzzle_%$(ext)
$(CARGO) build --profile $(PROFILE) --bin $(basename $(notdir $<))

$(outputdir)/puzzle_02: $(intcode_deps)
$(outputdir)/puzzle_05: $(intcode_deps)

.PHONY: lint
lint: lint-code lint-format
Expand Down
1 change: 1 addition & 0 deletions 2019/input_05.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1101,72,36,225,1101,87,26,225,2,144,13,224,101,-1872,224,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1102,66,61,225,1102,25,49,224,101,-1225,224,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,1101,35,77,224,101,-112,224,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1002,195,30,224,1001,224,-2550,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,1102,30,44,225,1102,24,21,225,1,170,117,224,101,-46,224,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1102,63,26,225,102,74,114,224,1001,224,-3256,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,58,22,225,101,13,17,224,101,-100,224,224,4,224,1002,223,8,223,101,6,224,224,1,224,223,223,1101,85,18,225,1001,44,7,224,101,-68,224,224,4,224,102,8,223,223,1001,224,5,224,1,223,224,223,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,7,677,226,224,102,2,223,223,1005,224,329,101,1,223,223,8,677,226,224,1002,223,2,223,1005,224,344,1001,223,1,223,1107,677,677,224,102,2,223,223,1005,224,359,1001,223,1,223,1107,226,677,224,102,2,223,223,1005,224,374,101,1,223,223,7,226,677,224,102,2,223,223,1005,224,389,101,1,223,223,8,226,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,226,677,224,1002,223,2,223,1005,224,419,1001,223,1,223,107,677,677,224,102,2,223,223,1005,224,434,101,1,223,223,1108,677,226,224,1002,223,2,223,1006,224,449,101,1,223,223,1108,677,677,224,102,2,223,223,1006,224,464,101,1,223,223,1007,677,226,224,102,2,223,223,1006,224,479,101,1,223,223,1008,226,226,224,102,2,223,223,1006,224,494,101,1,223,223,108,226,226,224,1002,223,2,223,1006,224,509,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,524,101,1,223,223,1107,677,226,224,102,2,223,223,1005,224,539,1001,223,1,223,108,226,677,224,1002,223,2,223,1005,224,554,101,1,223,223,1007,226,226,224,102,2,223,223,1005,224,569,101,1,223,223,8,226,226,224,102,2,223,223,1006,224,584,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,599,1001,223,1,223,107,226,677,224,1002,223,2,223,1005,224,614,1001,223,1,223,1108,226,677,224,102,2,223,223,1006,224,629,101,1,223,223,7,677,677,224,1002,223,2,223,1005,224,644,1001,223,1,223,108,677,677,224,102,2,223,223,1005,224,659,101,1,223,223,1007,677,677,224,102,2,223,223,1006,224,674,101,1,223,223,4,223,99,226
2 changes: 1 addition & 1 deletion 2019/src/bin/puzzle_02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::ops;
use aoc2019::intcode;

fn run_program(prog: &[i32], addr1_val: i32, addr2_val: i32) -> i32 {
let mut computer = intcode::Computer::new(prog);
let mut computer = intcode::Computer::new(prog, &[]);

computer.memory[1] = addr1_val;
computer.memory[2] = addr2_val;
Expand Down
20 changes: 20 additions & 0 deletions 2019/src/bin/puzzle_05.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::io;

use aoc2019::intcode;

fn main() {
let diagnostic_program = intcode::parse_program(io::stdin());

println!(
"Part 1: {}",
intcode::Computer::new(&diagnostic_program, &[1])
.run()
.unwrap()
);
println!(
"Part 2: {}",
intcode::Computer::new(&diagnostic_program, &[5])
.run()
.unwrap()
);
}
153 changes: 133 additions & 20 deletions 2019/src/intcode.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::VecDeque;
use std::io;

pub fn parse_program(input: impl io::Read) -> Vec<i32> {
Expand All @@ -9,60 +10,172 @@ pub fn parse_program(input: impl io::Read) -> Vec<i32> {
.collect()
}

const INSTRUCTION_LEN: usize = 4;
enum Parameter {
Position(i32),
Immediate(i32),
}

enum Instruction {
Add(usize, usize, usize),
Multiply(usize, usize, usize),
Add(Parameter, Parameter, Parameter),
Multiply(Parameter, Parameter, Parameter),
Input(Parameter),
Output(Parameter),
JumpIfTrue(Parameter, Parameter),
JumpIfFalse(Parameter, Parameter),
LessThan(Parameter, Parameter, Parameter),
Equals(Parameter, Parameter, Parameter),
Halt,
}

pub struct Computer {
pub memory: Vec<i32>,
input: VecDeque<i32>,
output: Option<i32>,
ip: usize,
modes: i32,
}

impl Computer {
pub fn new(program: &[i32]) -> Self {
fn opcode(inst: i32) -> i32 {
inst % 100
}

fn param_modes(inst: i32) -> i32 {
inst / 100
}

pub fn new(program: &[i32], input: &[i32]) -> Self {
Self {
memory: program.to_vec(),
input: input.iter().copied().collect(),
output: None,
ip: 0,
modes: 0,
}
}

fn read(&mut self) -> i32 {
let val = self.memory[self.ip];
self.ip += 1;
val
}

fn next_param_mode(&mut self) -> i32 {
let val = self.modes % 10;
self.modes /= 10;
val
}

fn create_parameter(&mut self) -> Parameter {
let param_mode = self.next_param_mode();
match param_mode {
0 => Parameter::Position(self.read()),
1 => Parameter::Immediate(self.read()),
_ => unreachable!(),
}
}

fn fetch_instruction(&self) -> Instruction {
let memory = &self.memory[self.ip..];
let opcode = memory[0];
fn fetch_instruction(&mut self) -> Instruction {
let inst = self.read();
let opcode = Self::opcode(inst);
self.modes = Self::param_modes(inst);
match opcode {
1 => Instruction::Add(
usize::try_from(memory[1]).unwrap(),
usize::try_from(memory[2]).unwrap(),
usize::try_from(memory[3]).unwrap(),
self.create_parameter(),
self.create_parameter(),
self.create_parameter(),
),
2 => Instruction::Multiply(
usize::try_from(memory[1]).unwrap(),
usize::try_from(memory[2]).unwrap(),
usize::try_from(memory[3]).unwrap(),
self.create_parameter(),
self.create_parameter(),
self.create_parameter(),
),
3 => Instruction::Input(self.create_parameter()),
4 => Instruction::Output(self.create_parameter()),
5 => Instruction::JumpIfTrue(self.create_parameter(), self.create_parameter()),
6 => Instruction::JumpIfFalse(self.create_parameter(), self.create_parameter()),
7 => Instruction::LessThan(
self.create_parameter(),
self.create_parameter(),
self.create_parameter(),
),
8 => Instruction::Equals(
self.create_parameter(),
self.create_parameter(),
self.create_parameter(),
),
99 => Instruction::Halt,
_ => unreachable!(),
}
}

pub fn run(&mut self) {
fn value(&self, param: Parameter) -> i32 {
match param {
Parameter::Position(addr) => self.memory[usize::try_from(addr).unwrap()],
Parameter::Immediate(val) => val,
}
}

fn write(&mut self, param: Parameter, val: i32) {
let dst = match param {
Parameter::Position(addr) => usize::try_from(addr).unwrap(),
Parameter::Immediate(_) => unreachable!(),
};

self.memory[dst] = val;
}

fn jump(&mut self, new_ip: Parameter) {
self.ip = usize::try_from(self.value(new_ip)).unwrap();
}

pub fn run(&mut self) -> Option<i32> {
loop {
let instruction = self.fetch_instruction();
match instruction {
Instruction::Add(addr1, addr2, dst) => {
self.memory[dst] = self.memory[addr1] + self.memory[addr2];
self.ip += INSTRUCTION_LEN;
Instruction::Add(op1, op2, dst) => {
self.write(dst, self.value(op1) + self.value(op2));
}
Instruction::Multiply(op1, op2, dst) => {
self.write(dst, self.value(op1) * self.value(op2));
}
Instruction::Input(dst) => {
let val = self.input.pop_front().unwrap();
self.write(dst, val);
}
Instruction::Multiply(addr1, addr2, dst) => {
self.memory[dst] = self.memory[addr1] * self.memory[addr2];
self.ip += INSTRUCTION_LEN;
Instruction::Output(val) => {
self.output = Some(self.value(val));
}
Instruction::JumpIfTrue(cond, new_ip) => {
if self.value(cond) != 0 {
self.jump(new_ip);
}
}
Instruction::JumpIfFalse(cond, new_ip) => {
if self.value(cond) == 0 {
self.jump(new_ip);
}
}
Instruction::LessThan(lhs, rhs, dst) => self.write(
dst,
if self.value(lhs) < self.value(rhs) {
1
} else {
0
},
),
Instruction::Equals(lhs, rhs, dst) => self.write(
dst,
if self.value(lhs) == self.value(rhs) {
1
} else {
0
},
),
Instruction::Halt => break,
}
}

self.output
}
}

0 comments on commit 6dd5bf5

Please sign in to comment.