Day 17
This commit is contained in:
parent
62ff4680a5
commit
b9da7b7cf6
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue