aoc/year2016/day23.rs
1//! # Safe Cracking
2//!
3//! Like [`Day 12`] this problem is all about *reading* code not writing code.
4//!
5//! We could implement a brute force virtual machine without understanding the underlying code
6//! but it's much more efficient to analyse the code instead.
7//!
8//! The first thing we notice is that the following idiom is repeated several times:
9//!
10//! ```none
11//! inc x
12//! dec y
13//! jnz y -2
14//! ```
15//!
16//! This is equivalent to `x += y` only much less efficient. The `tgl` instruction eventually
17//! rewrites a `jnz` to `cpy` to allow the program loop to end.
18//!
19//! Analysis shows that the code is calculating the [factorial](https://en.wikipedia.org/wiki/Factorial)
20//! of `a` plus some constant offset. We can replace the entire code with a single multiplication.
21//! If we had emulated the raw instructions directly then it would have taken billions of
22//! iterations to get the answer.
23//!
24//! [`Day 12`]: crate::year2016::day12
25use crate::util::parse::*;
26
27/// Extract the constant offset from the assembunny code.
28pub fn parse(input: &str) -> u32 {
29 let lines: Vec<_> = input.lines().collect();
30 let first: u32 = lines[19].unsigned();
31 let second: u32 = lines[20].unsigned();
32 first * second
33}
34
35/// 7! plus some constant.
36pub fn part1(input: &u32) -> u32 {
37 5040 + input
38}
39
40/// 12! plus some constant.
41pub fn part2(input: &u32) -> u32 {
42 479001600 + input
43}