diff --git a/.gitignore b/.gitignore index 53eaa21..c977131 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target **/*.rs.bk +.vscode diff --git a/input/day02.txt b/input/day02.txt new file mode 100644 index 0000000..432f8db --- /dev/null +++ b/input/day02.txt @@ -0,0 +1 @@ +1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,9,19,1,19,5,23,2,6,23,27,1,6,27,31,2,31,9,35,1,35,6,39,1,10,39,43,2,9,43,47,1,5,47,51,2,51,6,55,1,5,55,59,2,13,59,63,1,63,5,67,2,67,13,71,1,71,9,75,1,75,6,79,2,79,6,83,1,83,5,87,2,87,9,91,2,9,91,95,1,5,95,99,2,99,13,103,1,103,5,107,1,2,107,111,1,111,5,0,99,2,14,0,0 \ No newline at end of file diff --git a/input/day05.txt b/input/day05.txt new file mode 100644 index 0000000..d89c0ae --- /dev/null +++ b/input/day05.txt @@ -0,0 +1 @@ +3,225,1,225,6,6,1100,1,238,225,104,0,1102,68,5,225,1101,71,12,225,1,117,166,224,1001,224,-100,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1001,66,36,224,101,-87,224,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1101,26,51,225,1102,11,61,224,1001,224,-671,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,1101,59,77,224,101,-136,224,224,4,224,1002,223,8,223,1001,224,1,224,1,223,224,223,1101,11,36,225,1102,31,16,225,102,24,217,224,1001,224,-1656,224,4,224,102,8,223,223,1001,224,1,224,1,224,223,223,101,60,169,224,1001,224,-147,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1102,38,69,225,1101,87,42,225,2,17,14,224,101,-355,224,224,4,224,102,8,223,223,1001,224,2,224,1,224,223,223,1002,113,89,224,101,-979,224,224,4,224,1002,223,8,223,1001,224,7,224,1,224,223,223,1102,69,59,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,7,677,677,224,1002,223,2,223,1006,224,329,1001,223,1,223,1007,226,226,224,1002,223,2,223,1006,224,344,1001,223,1,223,1108,226,677,224,102,2,223,223,1005,224,359,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,374,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,389,101,1,223,223,7,226,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,677,226,224,102,2,223,223,1005,224,419,101,1,223,223,1008,226,226,224,102,2,223,223,1006,224,434,101,1,223,223,107,226,226,224,1002,223,2,223,1005,224,449,1001,223,1,223,108,226,677,224,102,2,223,223,1005,224,464,101,1,223,223,1108,677,226,224,102,2,223,223,1005,224,479,101,1,223,223,1007,226,677,224,102,2,223,223,1006,224,494,101,1,223,223,107,677,677,224,102,2,223,223,1005,224,509,101,1,223,223,108,677,677,224,102,2,223,223,1006,224,524,1001,223,1,223,8,226,677,224,102,2,223,223,1005,224,539,101,1,223,223,107,677,226,224,102,2,223,223,1005,224,554,1001,223,1,223,8,226,226,224,102,2,223,223,1006,224,569,1001,223,1,223,7,677,226,224,1002,223,2,223,1005,224,584,1001,223,1,223,1108,226,226,224,102,2,223,223,1005,224,599,1001,223,1,223,1107,677,677,224,1002,223,2,223,1006,224,614,1001,223,1,223,1007,677,677,224,1002,223,2,223,1006,224,629,1001,223,1,223,108,226,226,224,102,2,223,223,1005,224,644,1001,223,1,223,8,677,226,224,1002,223,2,223,1005,224,659,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226 \ No newline at end of file diff --git a/input/input05.txt b/input/input05.txt new file mode 100644 index 0000000..d89c0ae --- /dev/null +++ b/input/input05.txt @@ -0,0 +1 @@ +3,225,1,225,6,6,1100,1,238,225,104,0,1102,68,5,225,1101,71,12,225,1,117,166,224,1001,224,-100,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1001,66,36,224,101,-87,224,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1101,26,51,225,1102,11,61,224,1001,224,-671,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,1101,59,77,224,101,-136,224,224,4,224,1002,223,8,223,1001,224,1,224,1,223,224,223,1101,11,36,225,1102,31,16,225,102,24,217,224,1001,224,-1656,224,4,224,102,8,223,223,1001,224,1,224,1,224,223,223,101,60,169,224,1001,224,-147,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1102,38,69,225,1101,87,42,225,2,17,14,224,101,-355,224,224,4,224,102,8,223,223,1001,224,2,224,1,224,223,223,1002,113,89,224,101,-979,224,224,4,224,1002,223,8,223,1001,224,7,224,1,224,223,223,1102,69,59,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,7,677,677,224,1002,223,2,223,1006,224,329,1001,223,1,223,1007,226,226,224,1002,223,2,223,1006,224,344,1001,223,1,223,1108,226,677,224,102,2,223,223,1005,224,359,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,374,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,389,101,1,223,223,7,226,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,677,226,224,102,2,223,223,1005,224,419,101,1,223,223,1008,226,226,224,102,2,223,223,1006,224,434,101,1,223,223,107,226,226,224,1002,223,2,223,1005,224,449,1001,223,1,223,108,226,677,224,102,2,223,223,1005,224,464,101,1,223,223,1108,677,226,224,102,2,223,223,1005,224,479,101,1,223,223,1007,226,677,224,102,2,223,223,1006,224,494,101,1,223,223,107,677,677,224,102,2,223,223,1005,224,509,101,1,223,223,108,677,677,224,102,2,223,223,1006,224,524,1001,223,1,223,8,226,677,224,102,2,223,223,1005,224,539,101,1,223,223,107,677,226,224,102,2,223,223,1005,224,554,1001,223,1,223,8,226,226,224,102,2,223,223,1006,224,569,1001,223,1,223,7,677,226,224,1002,223,2,223,1005,224,584,1001,223,1,223,1108,226,226,224,102,2,223,223,1005,224,599,1001,223,1,223,1107,677,677,224,1002,223,2,223,1006,224,614,1001,223,1,223,1007,677,677,224,1002,223,2,223,1006,224,629,1001,223,1,223,108,226,226,224,102,2,223,223,1005,224,644,1001,223,1,223,8,677,226,224,1002,223,2,223,1005,224,659,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226 \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 1ac9056..2bad024 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ mod tasks; fn main() { - tasks::day08::run(); + tasks::day05::run(); } diff --git a/src/tasks/day05.rs b/src/tasks/day05.rs new file mode 100644 index 0000000..8b2d4d9 --- /dev/null +++ b/src/tasks/day05.rs @@ -0,0 +1,157 @@ +#[allow(dead_code)] +pub fn run() { + let input = std::fs::read_to_string("input/day05.txt").unwrap(); + let ram: Vec = input + .split(",") + .map(|s| s.parse::().unwrap()) + .collect(); + task1(ram.clone()); +} + +struct IntCodeComputer { + input_storage: Vec, + output_storage: Vec, + pc: usize, + ram: Vec, +} + +#[derive(PartialEq, Debug)] +enum OpCode { + Add, + Multiply, + Input, + Output, + Terminate, +} + +#[derive(Debug)] +enum OpParam { + Immediate(i32), + Memory(usize), +} + +impl OpParam { + fn from(val: i32, type_number: i32) -> Self { + match type_number { + 0 => OpParam::Memory(val as usize), + 1 => OpParam::Immediate(val), + _ => unreachable!("unexpected parameter"), + } + } + + fn retrieve(&self, memory: &Vec) -> i32 { + match self { + OpParam::Immediate(v) => *v, + OpParam::Memory(i) => memory[*i], + } + } + + fn store(&self, memory: &mut Vec, value: i32) { + match self { + OpParam::Immediate(_) => panic!("cannot save to immediate position"), + OpParam::Memory(i) => memory[*i] = value, + } + } +} + +#[derive(Debug)] +struct Op { + opcode: OpCode, + params: Vec, +} + +impl Op { + fn from(pc: usize, memory: &Vec) -> Self { + //opcode: 123xx -> 1, 2, 3: parameter type for parameters 1-3, xx = actual op code + let mut opcode = memory[pc]; + let p_type1 = opcode / 10_000; + opcode %= 10_000; + let p_type2 = opcode / 1000; + opcode %= 1000; + let p_type3 = opcode / 100; + opcode %= 100; + match opcode { + 1 => Op { + opcode: OpCode::Add, + params: vec![ + OpParam::from(memory[pc + 1], p_type3), + OpParam::from(memory[pc + 2], p_type2), + OpParam::from(memory[pc + 3], p_type1), + ], + }, + 2 => Op { + opcode: OpCode::Multiply, + params: vec![ + OpParam::from(memory[pc + 1], p_type3), + OpParam::from(memory[pc + 2], p_type2), + OpParam::from(memory[pc + 3], p_type1), + ], + }, + 3 => Op { + opcode: OpCode::Input, + params: vec![OpParam::from(memory[pc + 1], p_type3)], + }, + 4 => Op { + opcode: OpCode::Output, + params: vec![OpParam::from(memory[pc + 1], p_type3)], + }, + 99 => Op { + opcode: OpCode::Terminate, + params: vec![], + }, + _ => unreachable!("unknown op code {}", opcode), + } + } +} + +impl IntCodeComputer { + fn new(input: Vec, memory: Vec) -> Self { + IntCodeComputer { + input_storage: input, + output_storage: Vec::new(), + pc: 0, + ram: memory, + } + } + + fn run_until_end(&mut self) { + let mut op = Op::from(self.pc, &self.ram); + let mut inputs = self.input_storage.iter(); + while op.opcode != OpCode::Terminate { + match op.opcode { + OpCode::Add => { + let r = op.params[0].retrieve(&self.ram) + op.params[1].retrieve(&self.ram); + op.params[2].store(&mut self.ram, r); + self.pc += 4; + } + OpCode::Multiply => { + let r = op.params[0].retrieve(&self.ram) * op.params[1].retrieve(&self.ram); + op.params[2].store(&mut self.ram, r); + self.pc += 4; + } + OpCode::Input => { + let v = inputs.next().expect("Not enough inputs given"); + op.params[0].store(&mut self.ram, *v); + self.pc += 2; + } + OpCode::Output => { + self.output_storage.push(op.params[0].retrieve(&self.ram)); + self.pc += 2; + } + OpCode::Terminate => {} + } + op = Op::from(self.pc, &self.ram); + } + } + + fn get_output(&self) -> &[i32] { + self.output_storage.as_slice() + } +} + +fn task1(ram: Vec) { + let mut computer = IntCodeComputer::new(vec![1], ram); + computer.run_until_end(); + println!("{:?}", computer.get_output()); + println!("Task 1: {}", computer.get_output().last().unwrap()); +} diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index cb25c41..b42f001 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -1,5 +1,6 @@ pub mod day01; pub mod day03; pub mod day04; +pub mod day05; pub mod day06; pub mod day08;