From 2792304040585562c2ec07c8f82599e420adc8db Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 12 Nov 2023 21:25:31 +0100 Subject: [PATCH] Day 19 part 1. --- input/day19.txt | 37 +++++++++ src/main.rs | 2 +- src/tasks/day19.rs | 202 +++++++++++++++++++++++++++++++++++++++++++++ src/tasks/mod.rs | 1 + 4 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 input/day19.txt create mode 100644 src/tasks/day19.rs diff --git a/input/day19.txt b/input/day19.txt new file mode 100644 index 0000000..f5c8d13 --- /dev/null +++ b/input/day19.txt @@ -0,0 +1,37 @@ +#ip 4 +addi 4 16 4 +seti 1 9 5 +seti 1 5 2 +mulr 5 2 1 +eqrr 1 3 1 +addr 1 4 4 +addi 4 1 4 +addr 5 0 0 +addi 2 1 2 +gtrr 2 3 1 +addr 4 1 4 +seti 2 6 4 +addi 5 1 5 +gtrr 5 3 1 +addr 1 4 4 +seti 1 2 4 +mulr 4 4 4 +addi 3 2 3 +mulr 3 3 3 +mulr 4 3 3 +muli 3 11 3 +addi 1 5 1 +mulr 1 4 1 +addi 1 2 1 +addr 3 1 3 +addr 4 0 4 +seti 0 2 4 +setr 4 8 1 +mulr 1 4 1 +addr 4 1 1 +mulr 4 1 1 +muli 1 14 1 +mulr 1 4 1 +addr 3 1 3 +seti 0 0 0 +seti 0 2 4 \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 49e35d9..4fc4acd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,3 @@ fn main() { - aoc_2018::tasks::day16::task2(); + aoc_2018::tasks::day19::task1(); } diff --git a/src/tasks/day19.rs b/src/tasks/day19.rs new file mode 100644 index 0000000..40f63d7 --- /dev/null +++ b/src/tasks/day19.rs @@ -0,0 +1,202 @@ +use std::ops::{BitAnd, BitOr}; + +pub fn task1() { + let input = include_str!("../../input/day19.txt"); + let result = run1(input); + + println!("Day 19 part 1: {result}"); +} + +fn run1(input: &str) -> i32 { + let (config, program) = input.split_once("\n").unwrap(); + let ip_register: usize = config.split_once(" ").unwrap().1.parse().unwrap(); + + let program: Vec = program.lines().map(parse_instruction).collect(); + + let mut registers: Registers = [0i32; 6]; + let mut ip = 0; + loop { + //print!("ip={ip}, {registers:?}"); + + registers[ip_register] = ip as i32; + let instruction = program.get(ip).unwrap(); + + //print!("{instruction:?}"); + + let op: Op = instruction.opcode; + registers = op.process(registers, *instruction); + + //println!("{registers:?}"); + + ip = registers[ip_register] as usize; + ip += 1; + + if program.get(ip).is_none() { + break; + } + } + registers[0] +} + +fn parse_instruction(instruction: &str) -> Instruction { + let instruction: Vec<_> = instruction.split(" ").collect(); + let opcode = match instruction[0] { + "addr" => Op::AddR, + "addi" => Op::AddI, + "mulr" => Op::MulR, + "muli" => Op::MulI, + "banr" => Op::BanR, + "bani" => Op::BanI, + "borr" => Op::BorR, + "bori" => Op::BorI, + "setr" => Op::SetR, + "seti" => Op::SetI, + "gtir" => Op::GtIR, + "gtri" => Op::GtRI, + "gtrr" => Op::GtRR, + "eqir" => Op::EqIR, + "eqri" => Op::EqRI, + "eqrr" => Op::EqRR, + &_ => { + panic!("unknown op {}", instruction[0]) + } + }; + let instruction = Instruction { + opcode, + a: instruction[1].parse().unwrap(), + b: instruction[2].parse().unwrap(), + c: instruction[3].parse().unwrap(), + }; + instruction +} + +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +enum Op { + AddR, + AddI, + MulR, + MulI, + BanR, + BanI, + BorR, + BorI, + SetR, + SetI, + GtIR, + GtRI, + GtRR, + EqIR, + EqRI, + EqRR, +} + +impl Op { + fn process(&self, registers: Registers, instruction: Instruction) -> Registers { + let mut result = registers.clone(); + + match self { + Op::AddR => { + result[instruction.c] = result[instruction.a] + result[instruction.b]; + } + Op::AddI => { + result[instruction.c] = result[instruction.a] + instruction.b as i32; + } + Op::MulR => { + result[instruction.c] = result[instruction.a] * result[instruction.b]; + } + Op::MulI => { + result[instruction.c] = result[instruction.a] * instruction.b as i32; + } + Op::BanR => { + result[instruction.c] = result[instruction.a].bitand(result[instruction.b]); + } + Op::BanI => { + result[instruction.c] = result[instruction.a].bitand(instruction.b as i32); + } + Op::BorR => { + result[instruction.c] = result[instruction.a].bitor(result[instruction.b]); + } + Op::BorI => { + result[instruction.c] = result[instruction.a].bitor(instruction.b as i32); + } + Op::SetR => { + result[instruction.c] = result[instruction.a]; + } + Op::SetI => { + result[instruction.c] = instruction.a as i32; + } + Op::GtIR => { + result[instruction.c] = if instruction.a as i32 > result[instruction.b] { + 1 + } else { + 0 + } + } + Op::GtRI => { + result[instruction.c] = if result[instruction.a] > instruction.b as i32 { + 1 + } else { + 0 + } + } + Op::GtRR => { + result[instruction.c] = if result[instruction.a] > result[instruction.b] { + 1 + } else { + 0 + } + } + Op::EqIR => { + result[instruction.c] = if instruction.a as i32 == result[instruction.b] { + 1 + } else { + 0 + } + } + Op::EqRI => { + result[instruction.c] = if result[instruction.a] == instruction.b as i32 { + 1 + } else { + 0 + } + } + Op::EqRR => { + result[instruction.c] = if result[instruction.a] == result[instruction.b] { + 1 + } else { + 0 + } + } + } + + result + } +} + +type Registers = [i32; 6]; + +#[derive(Copy, Clone, Debug)] +struct Instruction { + opcode: Op, + a: usize, + b: usize, + c: usize, +} + +#[cfg(test)] +mod test { + use crate::tasks::day19::run1; + + #[test] + fn example1() { + let input = "#ip 0\n\ + seti 5 0 1\n\ + seti 6 0 2\n\ + addi 0 1 0\n\ + addr 1 2 3\n\ + setr 1 0 0\n\ + seti 8 0 4\n\ + seti 9 0 5"; + assert_eq!(run1(input), 6); + } +} diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index a0f0eb9..bbd2439 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -16,6 +16,7 @@ pub mod day15; pub mod day16; pub mod day17; pub mod day18; +pub mod day19; pub mod day20; pub mod day22; pub mod day23;