1use crate::util::parse::*;
12
13type Input = [i32; 3];
14
15pub fn parse(input: &str) -> Input {
16 let code: Vec<_> = input.iter_unsigned().collect();
17
18 let c = check(&code, 0, 0) as i32;
19 let a = check(&code, 1, 0) as i32;
20 let b = check(&code, 0, 1) as i32;
21
22 [a - c, b - c, c]
23}
24
25pub fn part1([a, b, c]: &Input) -> i32 {
26 a * 12 + b * 2 + c
27}
28
29pub fn part2([a, b, c]: &Input) -> i32 {
30 (0..100)
31 .find_map(|x| {
32 let y = (19690720 - a * x - c) / b;
33 (a * x + b * y + c == 19690720 && (0..100).contains(&y)).then_some(100 * x + y)
34 })
35 .unwrap()
36}
37
38fn check(input: &[usize], first: usize, second: usize) -> usize {
39 let mut code = input.to_vec();
40 code[1] = first;
41 code[2] = second;
42
43 execute(&mut code)
44}
45
46fn execute(code: &mut [usize]) -> usize {
47 let mut pc = 0;
48
49 loop {
50 match code[pc] {
51 1 => code[code[pc + 3]] = code[code[pc + 1]] + code[code[pc + 2]],
52 2 => code[code[pc + 3]] = code[code[pc + 1]] * code[code[pc + 2]],
53 _ => break code[0],
54 }
55 pc += 4;
56 }
57}