1use crate::intcode::Interpreter;
2use crate::intcode::features::Day02Features;
3use utils::prelude::*;
4
5#[derive(Clone, Debug)]
10pub struct Day02 {
11 interpreter: Interpreter,
12}
13
14const PART2_TARGET: i64 = 19_690_720;
15
16impl Day02 {
17 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
18 Ok(Self {
19 interpreter: Interpreter::parse(input, 3)?,
20 })
21 }
22
23 #[must_use]
24 pub fn part1(&self) -> i64 {
25 self.run(12, 2)
26 }
27
28 #[must_use]
29 pub fn part2(&self) -> u32 {
30 let mut noun_lo = 0u32;
31 let mut noun_hi = 99u32;
32 while noun_lo + 1 < noun_hi {
33 let mid = noun_lo + (noun_hi - noun_lo) / 2;
34 if self.run(mid as i64, 0) <= PART2_TARGET {
35 noun_lo = mid;
36 } else {
37 noun_hi = mid;
38 }
39 }
40
41 let mut verb_lo = 0u32;
42 let mut verb_hi = 99u32;
43 while verb_lo + 1 < verb_hi {
44 let mid = verb_lo + (verb_hi - verb_lo) / 2;
45 if self.run(noun_lo as i64, mid as i64) <= PART2_TARGET {
46 verb_lo = mid;
47 } else {
48 verb_hi = mid;
49 }
50 }
51
52 assert_eq!(
53 self.run(noun_lo as i64, verb_lo as i64),
54 PART2_TARGET,
55 "no solution found"
56 );
57
58 noun_lo * 100 + verb_lo
59 }
60
61 fn run(&self, noun: i64, verb: i64) -> i64 {
62 let mut interpreter = self.interpreter.clone();
63 interpreter.mem[1] = noun;
64 interpreter.mem[2] = verb;
65
66 let _ = interpreter.run::<Day02Features>();
67
68 interpreter.mem[0]
69 }
70}
71
72examples!(Day02 -> (i64, u32) []);