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
use super::super::TRUST;
const CASE: u8 = b'a' - b'A';
pub fn inverses(x: u8, y: u8) -> bool {
CASE == match (x, y) {
(a, b) if a > b => a - b,
(a, b) if b > a => b - a,
_ => 0,
}
}
pub fn part1(input: &[u8]) -> usize {
let mut last: Vec<u8> = Vec::from(input);
let mut current: Vec<u8> = Vec::with_capacity(last.len());
let mut reduced = true;
while reduced {
reduced = false;
let mut index = 0;
while index < last.len() {
let unit = last[index];
let next = if index + 1 < last.len() {
last[index + 1]
} else {
0
};
if inverses(unit, next) {
reduced = true;
index += 2;
continue;
}
current.push(unit);
index += 1;
}
last.clear();
last.extend(current.drain(..))
}
last.len()
}
pub fn part2(input: &str) -> usize {
(b'a'..=b'z')
.map(|u| (u as char, ((u - CASE) as char)))
.map(|(l, u)| part1(input.replace(l, "").replace(u, "").as_bytes()))
.min()
.expect(TRUST)
}
#[test]
fn examples() {
let input = "dabAcCaCBAcCcaDA";
assert_eq!(10, part1(input.as_bytes()));
assert_eq!(4, part2(input));
}
#[test]
fn solution() {
let input = include_str!("input/5");
assert_eq!(11310, part1(input.as_bytes()));
assert_eq!(6020, part2(input))
}