Skip to main content

advent_of_code/year2019/
day13.rs

1use super::int_code::{Program, Word};
2use crate::input::Input;
3
4pub fn solve(input: &Input) -> Result<Word, String> {
5    let mut program = Program::parse(input.text)?;
6
7    let is_part_one = input.is_part_one();
8
9    // "Memory address 0 represents the number of quarters that have been
10    // inserted; set it to 2 to play for free."
11    if !is_part_one {
12        program.write_memory(0, 2);
13    }
14
15    let mut current_score = 0;
16    let mut ball_x = -1;
17    let mut paddle_x = -1;
18
19    loop {
20        let output = program.run_for_output()?;
21        output.chunks_exact(3).for_each(|chunk| {
22            let (x, y, third) = (chunk[0], chunk[1], chunk[2]);
23            if x == -1 && y == 0 {
24                current_score = third;
25            } else {
26                match third {
27                    3 => paddle_x = x,
28                    4 => ball_x = x,
29                    _ => {}
30                }
31            }
32        });
33
34        if is_part_one {
35            return Ok(output
36                .iter()
37                .skip(2)
38                .step_by(3)
39                .filter(|&&t| t == 2)
40                .count() as Word);
41        }
42
43        if program.is_halted() {
44            break;
45        }
46
47        program.input(ball_x.cmp(&paddle_x) as Word);
48    }
49
50    Ok(current_score)
51}
52
53#[test]
54pub fn tests_part1() {
55    assert_eq!(
56        solve(&Input::part_one(include_str!("day13_input.txt"))),
57        Ok(462)
58    );
59}
60
61#[test]
62fn tests_part2() {
63    assert_eq!(
64        solve(&Input::part_two(include_str!("day13_input.txt"))),
65        Ok(23981)
66    );
67}