diff --git a/src/day2.rs b/src/day2.rs index b9bdde5..27c50a7 100644 --- a/src/day2.rs +++ b/src/day2.rs @@ -1,24 +1,70 @@ use std; -fn compute_intcode(p: &mut Vec) { - for idx in (0..(p.len())).step_by(4) { - match p[idx] { - 1 => { - let left = p[idx + 1]; - let right = p[idx + 2]; - let res = p[idx + 3]; - p[res] = p[left] + p[right]; - } - 2 => { - let left = p[idx + 1]; - let right = p[idx + 2]; - let res = p[idx + 3]; - p[res] = p[left] * p[right]; - } - 99 => break, - _ => panic!("invalid opcode"), +struct Params { + op1: usize, + op2: usize, + result: usize, +} + +enum Instruction { + Add(Params), + Mul(Params), + GetParam(usize), + Start, + Halt, +} + +struct IntcodeComputer { + memory: Vec, + output: Vec, + instruction: Instruction, + ip: usize, // instruction pointer +} + +impl IntcodeComputer { + fn new(memory: Vec) -> Self { + IntcodeComputer { + memory, + output: vec![], + instruction: Instruction::Start, + ip: 0, + } + } + fn add(&mut self) { + let op = self.get_params(); + self.memory[op.result] = self.memory[op.op1] + self.memory[op.op2] + } + fn mul(&mut self) { + let op = self.get_params(); + self.memory[op.result] = self.memory[op.op1] * self.memory[op.op2] + } + fn get_params(&mut self) -> Params { + Params { + op1: self.next(), + op2: self.next(), + result: self.next(), } } + fn halt(&mut self) { + self.instruction = Instruction::Halt; + } + fn next(&mut self) -> usize { + self.ip += 1; + self.memory[self.ip] + } + fn tick(&mut self) { + match self.next() { + 1 => self.add(), + 2 => self.mul(), + 99 => self.halt(), + _ => panic!("invalid input code"), + } + } +} + +fn compute_intcode(p: &mut Vec) -> Vec { + let computer = IntcodeComputer::new(p); + while } pub fn part_one() { @@ -31,9 +77,7 @@ pub fn part_one() { input[1] = 12; input[2] = 2; - compute_intcode(&mut input); - - println!("Intcode [0] is: {}", input[0]); + println!("Intcode [0] is: {}", compute_intcode(&mut input)[0]); } pub fn part_two() { @@ -53,8 +97,8 @@ pub fn part_two() { input[1] = i; for j in 0..99 { input[2] = j; - let mut computed = input.clone(); - compute_intcode(&mut computed); + let mut input_guess = input.clone(); + let computed = compute_intcode(&mut input_guess); found = computed[0] == lookup_num; @@ -77,19 +121,20 @@ pub fn part_two() { #[test] fn test_part_one() { - let mut intcode = vec![1, 0, 0, 0, 99]; - compute_intcode(&mut intcode); - assert_eq!(intcode, vec!(2, 0, 0, 0, 99)); - - let mut intcode = vec![2, 3, 0, 3, 99]; - compute_intcode(&mut intcode); - assert_eq!(intcode, vec!(2, 3, 0, 6, 99)); - - let mut intcode = vec![2, 4, 4, 5, 99, 0]; - compute_intcode(&mut intcode); - assert_eq!(intcode, vec!(2, 4, 4, 5, 99, 9801)); - - let mut intcode = vec![1, 1, 1, 4, 99, 5, 6, 0, 99]; - compute_intcode(&mut intcode); - assert_eq!(intcode, vec!(30, 1, 1, 4, 2, 5, 6, 0, 99)); + assert_eq!( + compute_intcode(&mut vec!(1, 0, 0, 0, 99)), + vec!(2, 0, 0, 0, 99) + ); + assert_eq!( + compute_intcode(&mut vec!(2, 3, 0, 3, 99)), + vec!(2, 3, 0, 6, 99) + ); + assert_eq!( + compute_intcode(&mut vec!(2, 4, 4, 5, 99, 0)), + vec!(2, 4, 4, 5, 99, 9801) + ); + assert_eq!( + compute_intcode(&mut vec!(1, 1, 1, 4, 99, 5, 6, 0, 99)), + vec!(30, 1, 1, 4, 2, 5, 6, 0, 99) + ); }