This commit is contained in:
sepia 2024-12-17 14:52:16 -06:00
parent 62ff4680a5
commit b9da7b7cf6
2 changed files with 113 additions and 1 deletions

110
src/day17.rs Normal file
View File

@ -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<u8>,
pointer: usize,
}
impl StrangeDevice {
fn run(&mut self) -> Vec<u8> {
let mut output: Vec<u8> = 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::<u64>()
.unwrap()
})
.collect_tuple()
.unwrap();
let tape = program_input
.split_whitespace()
.last()
.unwrap()
.split(",")
.map(|o| o.parse::<u8>().unwrap())
.collect();
Self {
a,
b,
c,
tape,
pointer: 0,
}
}
}

View File

@ -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 {