Advent of code day 17, rough doing the decompilation
This commit is contained in:
4
advent_of_code/2024/17/Cargo.toml
Normal file
4
advent_of_code/2024/17/Cargo.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[package]
|
||||||
|
name = "main"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
5
advent_of_code/2024/17/input.txt
Normal file
5
advent_of_code/2024/17/input.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Register A: 52042868
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 2,4,1,7,7,5,0,3,4,4,1,7,5,5,3,0
|
||||||
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
5
advent_of_code/2024/17/test.txt
Normal file
5
advent_of_code/2024/17/test.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Register A: 729
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,1,5,4,3,0
|
||||||
5
advent_of_code/2024/17/test2.txt
Normal file
5
advent_of_code/2024/17/test2.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Register A: 2024
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,3,5,4,3,0
|
||||||
Reference in New Issue
Block a user