advent_of_code/common/
character_recognition.rs

1pub const CHAR_WIDTH: usize = 5;
2pub const CHAR_HEIGHT: usize = 6;
3
4fn recognize_letter(
5    r1: &[bool],
6    r2: &[bool],
7    r3: &[bool],
8    r4: &[bool],
9    r5: &[bool],
10    r6: &[bool],
11) -> Result<char, String> {
12    Ok(match (r1, r2, r3, r4, r5, r6) {
13        (
14            [false, true, true, false, false],
15            [true, false, false, true, false],
16            [true, false, false, true, false],
17            [true, true, true, true, false],
18            [true, false, false, true, false],
19            [true, false, false, true, false],
20        ) => 'A',
21
22        (
23            [true, true, true, false, false],
24            [true, false, false, true, false],
25            [true, true, true, false, false],
26            [true, false, false, true, false],
27            [true, false, false, true, false],
28            [true, true, true, false, false],
29        ) => 'B',
30
31        (
32            [false, true, true, false, false],
33            [true, false, false, true, false],
34            [true, false, false, false, false],
35            [true, false, false, false, false],
36            [true, false, false, true, false],
37            [false, true, true, false, false],
38        ) => 'C',
39
40        (
41            [true, true, true, true, false],
42            [true, false, false, false, false],
43            [true, true, true, false, false],
44            [true, false, false, false, false],
45            [true, false, false, false, false],
46            [true, true, true, true, false],
47        ) => 'E',
48
49        (
50            [true, true, true, true, false],
51            [true, false, false, false, false],
52            [true, true, true, false, false],
53            [true, false, false, false, false],
54            [true, false, false, false, false],
55            [true, false, false, false, false],
56        ) => 'F',
57
58        (
59            [false, true, true, false, false],
60            [true, false, false, true, false],
61            [true, false, false, false, false],
62            [true, false, true, true, false],
63            [true, false, false, true, false],
64            [false, true, true, true, false],
65        ) => 'G',
66
67        (
68            [true, false, false, true, false],
69            [true, false, false, true, false],
70            [true, true, true, true, false],
71            [true, false, false, true, false],
72            [true, false, false, true, false],
73            [true, false, false, true, false],
74        ) => 'H',
75
76        (
77            [false, true, true, true, false],
78            [false, false, true, false, false],
79            [false, false, true, false, false],
80            [false, false, true, false, false],
81            [false, false, true, false, false],
82            [false, true, true, true, false],
83        ) => 'I',
84
85        (
86            [false, false, true, true, false],
87            [false, false, false, true, false],
88            [false, false, false, true, false],
89            [false, false, false, true, false],
90            [true, false, false, true, false],
91            [false, true, true, false, false],
92        ) => 'J',
93
94        (
95            [true, false, false, true, false],
96            [true, false, true, false, false],
97            [true, true, false, false, false],
98            [true, false, true, false, false],
99            [true, false, true, false, false],
100            [true, false, false, true, false],
101        ) => 'K',
102
103        (
104            [true, false, false, false, false],
105            [true, false, false, false, false],
106            [true, false, false, false, false],
107            [true, false, false, false, false],
108            [true, false, false, false, false],
109            [true, true, true, true, false],
110        ) => 'L',
111
112        (
113            [false, true, true, false, false],
114            [true, false, false, true, false],
115            [true, false, false, true, false],
116            [true, false, false, true, false],
117            [true, false, false, true, false],
118            [false, true, true, false, false],
119        ) => 'O',
120
121        (
122            [true, true, true, false, false],
123            [true, false, false, true, false],
124            [true, false, false, true, false],
125            [true, true, true, false, false],
126            [true, false, false, false, false],
127            [true, false, false, false, false],
128        ) => 'P',
129
130        (
131            [true, true, true, false, false],
132            [true, false, false, true, false],
133            [true, false, false, true, false],
134            [true, true, true, false, false],
135            [true, false, true, false, false],
136            [true, false, false, true, false],
137        ) => 'R',
138
139        (
140            [false, true, true, true, false],
141            [true, false, false, false, false],
142            [true, false, false, false, false],
143            [false, true, true, false, false],
144            [false, false, false, true, false],
145            [true, true, true, false, false],
146        ) => 'S',
147
148        (
149            [true, false, false, true, false],
150            [true, false, false, true, false],
151            [true, false, false, true, false],
152            [true, false, false, true, false],
153            [true, false, false, true, false],
154            [false, true, true, false, false],
155        ) => 'U',
156
157        (
158            [true, false, false, false, true],
159            [true, false, false, false, true],
160            [false, true, false, true, false],
161            [false, false, true, false, false],
162            [false, false, true, false, false],
163            [false, false, true, false, false],
164        ) => 'Y',
165
166        (
167            [true, true, true, true, false],
168            [false, false, false, true, false],
169            [false, false, true, false, false],
170            [false, true, false, false, false],
171            [true, false, false, false, false],
172            [true, true, true, true, false],
173        ) => 'Z',
174
175        _ => {
176            return Err("Unrecognized character".to_string());
177        }
178    })
179}
180
181pub fn recognize(bytes: &[bool]) -> Result<String, String> {
182    if bytes.len() % (CHAR_WIDTH * CHAR_HEIGHT) != 0 {
183        return Err(format!(
184            "Input length is not a multiple of {}",
185            CHAR_WIDTH * CHAR_HEIGHT
186        ));
187    }
188    let num_letters = bytes.len() / (CHAR_WIDTH * CHAR_HEIGHT);
189    let all_width = CHAR_WIDTH * num_letters;
190    let mut result = String::with_capacity(num_letters);
191    for letter_idx in 0..num_letters {
192        result.push(recognize_letter(
193            &bytes[(letter_idx * CHAR_WIDTH)..((letter_idx + 1) * CHAR_WIDTH)],
194            &bytes[(letter_idx * CHAR_WIDTH + all_width)
195                ..((letter_idx + 1) * CHAR_WIDTH + all_width)],
196            &bytes[(letter_idx * CHAR_WIDTH + 2 * all_width)
197                ..((letter_idx + 1) * CHAR_WIDTH + 2 * all_width)],
198            &bytes[(letter_idx * CHAR_WIDTH + 3 * all_width)
199                ..((letter_idx + 1) * CHAR_WIDTH + 3 * all_width)],
200            &bytes[(letter_idx * CHAR_WIDTH + 4 * all_width)
201                ..((letter_idx + 1) * CHAR_WIDTH + 4 * all_width)],
202            &bytes[(letter_idx * CHAR_WIDTH + 5 * all_width)
203                ..((letter_idx + 1) * CHAR_WIDTH + 5 * all_width)],
204        )?);
205    }
206    Ok(result)
207}