From b9da7b7cf6b9d102fb65c7fd9cba5d2fb9db4617 Mon Sep 17 00:00:00 2001 From: sepia Date: Tue, 17 Dec 2024 14:52:16 -0600 Subject: [PATCH] Day 17 --- src/day17.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 4 +- 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/day17.rs diff --git a/src/day17.rs b/src/day17.rs new file mode 100644 index 0000000..a34f615 --- /dev/null +++ b/src/day17.rs @@ -0,0 +1,110 @@ +use itertools::Itertools; + +pub fn day17() { + let device = StrangeDevice::from_str(&crate::input(17)); + + let default_outputs = device.clone().run(); + println!( + "Default Output: {}", + default_outputs.iter().map(|v| format!("{}", v)).join(",") + ); + + let mut a = 0; + let mut len = 1; + loop { + let mut device = device.clone(); + device.a = a; + let output = device.run(); + + if (0..len).all(|i| output[i] == device.tape[device.tape.len() - len + i]) { + if len == 16 { + break; + } else { + len += 1; + a *= 8; + } + } else { + a += 1; + } + } + + println!("Quine for A = {}", a); +} + +#[derive(Debug, Clone)] +struct StrangeDevice { + a: u64, + b: u64, + c: u64, + tape: Vec, + pointer: usize, +} + +impl StrangeDevice { + fn run(&mut self) -> Vec { + let mut output: Vec = vec![]; + + while self.pointer < self.tape.len() - 1 { + let op = self.tape[self.pointer]; + let operand = self.tape[self.pointer + 1]; + let combo = match op { + 0..=3 => op as u64, + 4 => self.a, + 5 => self.b, + 6 => self.c, + _ => panic!(), + }; + + match op { + 0 => self.a = self.a / 2u64.pow(combo as u32), + 1 => self.b = self.b ^ operand as u64, + 2 => self.b = combo % 8, + 3 => { + if self.a != 0 { + self.pointer = operand as usize; + continue; + } + } + 4 => self.b = self.b ^ self.c, + 5 => output.push((combo % 8) as u8), + 6 => self.b = self.a / 2u64.pow(combo as u32), + 7 => self.c = self.a / 2u64.pow(combo as u32), + _ => unreachable!(), + } + self.pointer += 2; + } + + output + } + + fn from_str(input: &str) -> Self { + let (registers_input, program_input) = input.split("\n\n").collect_tuple().unwrap(); + + let (a, b, c) = registers_input + .lines() + .map(|line| { + line.split_whitespace() + .last() + .unwrap() + .parse::() + .unwrap() + }) + .collect_tuple() + .unwrap(); + let tape = program_input + .split_whitespace() + .last() + .unwrap() + .split(",") + .map(|o| o.parse::().unwrap()) + .collect(); + + Self { + a, + b, + c, + tape, + pointer: 0, + } + } +} diff --git a/src/main.rs b/src/main.rs index ce7a2f1..c6be92f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,10 +30,12 @@ mod day13; mod day14; #[allow(dead_code)] mod day15; +#[allow(dead_code)] mod day16; +mod day17; fn main() { - day16::day16(); + day17::day17(); } pub fn input(day: u8) -> String {