Advent of code day 17, rough doing the decompilation
This commit is contained in:
180
advent_of_code/2024/17/src/main.rs
Normal file
180
advent_of_code/2024/17/src/main.rs
Normal file
@@ -0,0 +1,180 @@
|
||||
fn parse(input: &str) -> (u64, u64, u64, Vec<u64>) {
|
||||
let lines: Vec<Vec<&str>> = input
|
||||
.lines()
|
||||
.map(|l| l.split_whitespace().collect())
|
||||
.collect();
|
||||
|
||||
(
|
||||
lines[0].last().unwrap().parse().unwrap(),
|
||||
lines[1].last().unwrap().parse().unwrap(),
|
||||
lines[2].last().unwrap().parse().unwrap(),
|
||||
lines
|
||||
.last()
|
||||
.unwrap()
|
||||
.last()
|
||||
.unwrap()
|
||||
.split(',')
|
||||
.map(|i| i.parse().unwrap())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn combo(a: u64, b: u64, c: u64, op: u64) -> u64 {
|
||||
match op {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => a,
|
||||
5 => b,
|
||||
6 => c,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_1(input: &str) -> String {
|
||||
let (a, b, c, ops) = parse(input);
|
||||
|
||||
stringify(solve(a, b, c, ops))
|
||||
}
|
||||
|
||||
fn solve(mut a: u64, mut b: u64, mut c: u64, ops: Vec<u64>) -> Vec<u64> {
|
||||
let mut ip = 0;
|
||||
let mut out: Vec<u64> = vec![];
|
||||
|
||||
while ip < ops.len() {
|
||||
let ins = *ops.get(ip).unwrap();
|
||||
let op = *ops.get(ip + 1).unwrap();
|
||||
match ins {
|
||||
0 => {
|
||||
// adv
|
||||
let result = a >> combo(a, b, c, op);
|
||||
a = result;
|
||||
ip += 2;
|
||||
}
|
||||
1 => {
|
||||
// bxl
|
||||
let result = b ^ op;
|
||||
b = result;
|
||||
ip += 2;
|
||||
}
|
||||
2 => {
|
||||
// bst
|
||||
let result = combo(a, b, c, op) % 8;
|
||||
b = result;
|
||||
ip += 2;
|
||||
}
|
||||
3 => {
|
||||
// jnz
|
||||
if a != 0 {
|
||||
ip = op as usize;
|
||||
} else {
|
||||
ip += 2;
|
||||
}
|
||||
}
|
||||
4 => {
|
||||
// bxc
|
||||
let result = b ^ c;
|
||||
b = result;
|
||||
ip += 2;
|
||||
}
|
||||
5 => {
|
||||
// out
|
||||
out.push(combo(a, b, c, op) % 8);
|
||||
ip += 2;
|
||||
}
|
||||
6 => {
|
||||
// bdv
|
||||
let result = a >> combo(a, b, c, op);
|
||||
b = result;
|
||||
ip += 2;
|
||||
}
|
||||
7 => {
|
||||
// cdv
|
||||
let result = a >> combo(a, b, c, op);
|
||||
c = result;
|
||||
ip += 2;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
fn stringify(ops: Vec<u64>) -> String {
|
||||
let out = ops
|
||||
.into_iter()
|
||||
.fold("".to_string(), |result, n| result + "," + &n.to_string());
|
||||
|
||||
out.as_str()[1..].to_string()
|
||||
}
|
||||
|
||||
// Decompilation of my program yields the following
|
||||
// 2,4,1,7,7,5,0,3,4,4,1,7,5,5,3,0
|
||||
//
|
||||
// while a:
|
||||
// b = a % 8
|
||||
// b = b ^ 7
|
||||
// c = a >> b
|
||||
// a = a >> 3
|
||||
// b = b ^ c
|
||||
// b = b ^ 7
|
||||
// out(b % 8)
|
||||
|
||||
fn solve_2(input: &str) -> u64 {
|
||||
fn find(ops: &[u64], ans: u64) -> Option<u64> {
|
||||
if ops.is_empty() {
|
||||
return Some(ans);
|
||||
}
|
||||
|
||||
for t in 0..8 {
|
||||
let a = ans << 3 | t;
|
||||
|
||||
let mut b = a % 8;
|
||||
b = b ^ 7;
|
||||
let c = a >> b;
|
||||
b = b ^ c;
|
||||
b = b ^ 7;
|
||||
let output = b % 8;
|
||||
|
||||
if output == *ops.last().unwrap() {
|
||||
let sub = find(&ops[..ops.len() - 1], a);
|
||||
if sub.is_some() {
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
let (_a, _b, _c, ops) = parse(input);
|
||||
|
||||
find(&ops[..], 0).unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, this is Patrick!");
|
||||
|
||||
let input = include_str!("../input.txt");
|
||||
|
||||
let result_1 = solve_1(input);
|
||||
println!("The final output of the program is {}", result_1);
|
||||
|
||||
let result_2 = solve_2(input);
|
||||
println!(
|
||||
"The lowest positive initial value for register A to get a copy of the program is {}",
|
||||
result_2
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1() {
|
||||
let test_input = include_str!("../test.txt");
|
||||
assert_eq!(solve_1(test_input), "4,6,3,5,6,3,5,2,1,0");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user