From f3c1072d08c82950f1e55006d8e401aae64ed61b Mon Sep 17 00:00:00 2001 From: hal8174 Date: Wed, 18 Dec 2024 21:54:34 +0100 Subject: [PATCH] Partial solve day 17 --- Cargo.lock | 1 + Cargo.toml | 1 + input/17-0a.in | 5 ++ input/17-0b.in | 5 ++ input/17-1.in | 5 ++ src/bin/17.rs | 166 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 183 insertions(+) create mode 100644 input/17-0a.in create mode 100644 input/17-0b.in create mode 100644 input/17-1.in create mode 100644 src/bin/17.rs diff --git a/Cargo.lock b/Cargo.lock index 44589ff..f0a2d4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,7 @@ dependencies = [ "image", "itertools 0.13.0", "memoize", + "rayon", "regex", ] diff --git a/Cargo.toml b/Cargo.toml index d142b41..97ed37b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" image = "0.25.5" itertools = "0.13.0" memoize = "0.4.2" +rayon = "1.10.0" regex = "1.11.1" diff --git a/input/17-0a.in b/input/17-0a.in new file mode 100644 index 0000000..f09839b --- /dev/null +++ b/input/17-0a.in @@ -0,0 +1,5 @@ +Register A: 729 +Register B: 0 +Register C: 0 + +Program: 0,1,5,4,3,0 diff --git a/input/17-0b.in b/input/17-0b.in new file mode 100644 index 0000000..4a91c26 --- /dev/null +++ b/input/17-0b.in @@ -0,0 +1,5 @@ +Register A: 2024 +Register B: 0 +Register C: 0 + +Program: 0,3,5,4,3,0 diff --git a/input/17-1.in b/input/17-1.in new file mode 100644 index 0000000..fb81fbe --- /dev/null +++ b/input/17-1.in @@ -0,0 +1,5 @@ +Register A: 27575648 +Register B: 0 +Register C: 0 + +Program: 2,4,1,2,7,5,4,1,1,3,5,5,0,3,3,0 diff --git a/src/bin/17.rs b/src/bin/17.rs new file mode 100644 index 0000000..41feadd --- /dev/null +++ b/src/bin/17.rs @@ -0,0 +1,166 @@ +use rayon::prelude::*; + +fn combo_operand(operand: u8, a: u64, b: u64, c: u64) -> u64 { + match operand { + 0..4 => operand as u64, + 4 => a, + 5 => b, + 6 => c, + _ => unreachable!(), + } +} + +fn run_program(program: &[u8], mut a: u64, mut b: u64, mut c: u64) -> Vec { + let mut i = 0; + + let mut output = Vec::new(); + + while let Some((&opcode, &operand)) = program.get(i).zip(program.get(i + 1)) { + // dbg!(i, a, b, c, opcode, operand); + match opcode { + 0 => { + a = a / (2u64.pow(combo_operand(operand, a, b, c) as u32)); + i += 2 + } + 1 => { + b ^= operand as u64; + i += 2; + } + 2 => { + b = combo_operand(operand, a, b, c) % 8; + i += 2 + } + 3 => { + if a != 0 { + i = operand as usize + } else { + i += 2; + } + } + 4 => { + b ^= c; + i += 2; + } + 5 => { + output.push((combo_operand(operand, a, b, c) % 8) as u8); + i += 2; + } + 6 => { + b = a / (2u64.pow(combo_operand(operand, a, b, c) as u32)); + i += 2 + } + 7 => { + c = a / (2u64.pow(combo_operand(operand, a, b, c) as u32)); + i += 2 + } + + _ => unreachable!(), + } + } + + output +} + +fn run_program_output(program: &[u8], mut a: u64, mut b: u64, mut c: u64) -> bool { + let mut i = 0; + + let mut o = 0; + + while let Some((&opcode, &operand)) = program.get(i).zip(program.get(i + 1)) { + // dbg!(i, a, b, c, opcode, operand); + match opcode { + 0 => { + a = a / (2u64.pow(combo_operand(operand, a, b, c) as u32)); + i += 2 + } + 1 => { + b ^= operand as u64; + i += 2; + } + 2 => { + b = combo_operand(operand, a, b, c) % 8; + i += 2 + } + 3 => { + if a != 0 { + i = operand as usize + } else { + i += 2; + } + } + 4 => { + b ^= c; + i += 2; + } + 5 => { + if program.len() >= o && program[o] != (combo_operand(operand, a, b, c) % 8) as u8 { + return false; + } + o += 1; + i += 2; + } + 6 => { + b = a / (2u64.pow(combo_operand(operand, a, b, c) as u32)); + i += 2 + } + 7 => { + c = a / (2u64.pow(combo_operand(operand, a, b, c) as u32)); + i += 2 + } + + _ => unreachable!(), + } + } + + o == program.len() +} + +fn main() { + let text = std::fs::read_to_string("input/17-1.in").unwrap(); + let mut lines = text.lines(); + let start_a = lines + .next() + .unwrap() + .split_once(": ") + .unwrap() + .1 + .parse::() + .unwrap(); + let start_b = lines + .next() + .unwrap() + .split_once(": ") + .unwrap() + .1 + .parse::() + .unwrap(); + let start_c = lines + .next() + .unwrap() + .split_once(": ") + .unwrap() + .1 + .parse::() + .unwrap(); + + let program = lines + .nth(1) + .unwrap() + .split_once(": ") + .unwrap() + .1 + .split(',') + .map(|c| c.parse::().unwrap()) + .collect::>(); + + println!("{:?}", run_program(&program, start_a, start_b, start_c)); + + let start = 1_000_000_000_000u64; + + let t = (start..start * 10) + .into_par_iter() + .find_first(|&i| run_program_output(&program, i, 0, 0)) + .unwrap(); + + println!("{t}"); +}