1use crate::intcode::features::Day09Features;
2use crate::intcode::{Event, Interpreter};
3use utils::prelude::*;
4
5#[derive(Clone, Debug)]
7pub struct Day13 {
8 interpreter: Interpreter,
9}
10
11const EMPTY: i64 = 0;
12const WALL: i64 = 1;
13const BLOCK: i64 = 2;
14const PADDLE: i64 = 3;
15const BALL: i64 = 4;
16
17impl Day13 {
18 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
19 Ok(Self {
20 interpreter: Interpreter::parse(input, 1)?,
21 })
22 }
23
24 #[must_use]
25 pub fn part1(&self) -> u32 {
26 let mut interpreter = self.interpreter.clone();
27 let mut blocks = 0;
28
29 while interpreter.next_output::<Day09Features>().is_some() {
30 let _ = interpreter.expect_output::<Day09Features>();
31 match interpreter.expect_output::<Day09Features>() {
32 EMPTY | WALL | PADDLE | BALL => {}
33 BLOCK => blocks += 1,
34 _ => panic!("no solution found: program returned invalid tile id"),
35 }
36 }
37
38 blocks
39 }
40
41 #[must_use]
42 pub fn part2(&self) -> i64 {
43 let mut interpreter = self.interpreter.clone();
44 interpreter.mem[0] = 2;
45
46 let mut score = 0;
47 let (mut ball_x, mut paddle_x) = (0i64, 0i64);
48
49 loop {
50 let x = match interpreter.run::<Day09Features>() {
51 Event::Halt => break score,
52 Event::Input => {
53 interpreter.push_input((ball_x - paddle_x).signum());
54 continue;
55 }
56 Event::Output(x) => x,
57 };
58 let y = interpreter.expect_output::<Day09Features>();
59 let tile = interpreter.expect_output::<Day09Features>();
60
61 if x == -1 && y == 0 {
62 score = tile;
63 continue;
64 }
65
66 match tile {
67 EMPTY | WALL | BLOCK => {}
68 PADDLE => paddle_x = x,
69 BALL => ball_x = x,
70 _ => panic!("no solution found: program returned invalid tile id"),
71 }
72 }
73 }
74}
75
76examples!(Day13 -> (u32, i64) []);