1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use crate::input::Input;

pub fn solve(input: &Input) -> Result<String, String> {
    #![allow(clippy::match_same_arms)]
    let mut code = String::new();
    let mut current_button = '5';

    for line in input.text.lines() {
        for direction in line.chars() {
            if input.is_part_one() {
                current_button = match (direction, current_button) {
                    ('U', '4') => '1',
                    ('U', '5') => '2',
                    ('U', '6') => '3',
                    ('U', '7') => '4',
                    ('U', '8') => '5',
                    ('U', '9') => '6',

                    ('R', '1') => '2',
                    ('R', '2') => '3',
                    ('R', '4') => '5',
                    ('R', '5') => '6',
                    ('R', '7') => '8',
                    ('R', '8') => '9',

                    ('D', '1') => '4',
                    ('D', '2') => '5',
                    ('D', '3') => '6',
                    ('D', '4') => '7',
                    ('D', '5') => '8',
                    ('D', '6') => '9',

                    ('L', '2') => '1',
                    ('L', '5') => '4',
                    ('L', '8') => '7',
                    ('L', '3') => '2',
                    ('L', '6') => '5',
                    ('L', '9') => '8',
                    _ => current_button,
                };
            } else {
                current_button = match (direction, current_button) {
                    ('U', '3') => '1',
                    ('U', '6') => '2',
                    ('U', '7') => '3',
                    ('U', '8') => '4',
                    ('U', 'A') => '6',
                    ('U', 'B') => '7',
                    ('U', 'C') => '8',
                    ('U', 'D') => 'B',

                    ('R', '2') => '3',
                    ('R', '3') => '4',
                    ('R', '5') => '6',
                    ('R', '6') => '7',
                    ('R', '7') => '8',
                    ('R', '8') => '9',
                    ('R', 'A') => 'B',
                    ('R', 'B') => 'C',

                    ('D', '1') => '3',
                    ('D', '2') => '6',
                    ('D', '3') => '7',
                    ('D', '4') => '8',
                    ('D', '6') => 'A',
                    ('D', '7') => 'B',
                    ('D', '8') => 'C',
                    ('D', 'B') => 'D',

                    ('L', '3') => '2',
                    ('L', '4') => '3',
                    ('L', '6') => '5',
                    ('L', '7') => '6',
                    ('L', '8') => '7',
                    ('L', '9') => '8',
                    ('L', 'B') => 'A',
                    ('L', 'C') => 'B',
                    _ => current_button,
                };
            }
        }

        code.push(current_button);
    }

    Ok(code)
}

#[test]
pub fn tests() {
    use crate::input::{test_part_one, test_part_two};

    let real_input = include_str!("day02_input.txt");
    test_part_one!(real_input => "38961".to_string());
    test_part_two!(real_input => "46C92".to_string());
}