advent_of_code/year2018/
day05.rs1use crate::input::Input;
2
3type PolymerUnit = u8;
4
5const fn destroys_each_other(a: PolymerUnit, b: PolymerUnit) -> bool {
6 a.eq_ignore_ascii_case(&b) && a != b
7}
8
9pub fn solve(input: &Input) -> Result<usize, String> {
10 let input_polymer = input.text.as_bytes();
11 let mut new_polymer = Vec::<PolymerUnit>::with_capacity(input_polymer.len());
12
13 let candidates_for_removal = input.part_values(0..=0, b'a'..=b'z');
14
15 candidates_for_removal
16 .map(|to_remove_lower| {
17 new_polymer.clear();
18
19 for &unit in input_polymer
20 .iter()
21 .filter(|unit| !unit.eq_ignore_ascii_case(&to_remove_lower))
22 {
23 let unit_reacts_with_last = new_polymer
24 .last()
25 .is_some_and(|&last| destroys_each_other(unit, last));
26
27 if unit_reacts_with_last {
28 new_polymer.pop();
29 } else {
30 new_polymer.push(unit);
31 }
32 }
33
34 new_polymer.len()
35 })
36 .min()
37 .ok_or_else(|| "Internal error".to_string())
38}
39
40#[test]
41fn tests() {
42 test_part_one!("aA"=>0);
43 test_part_one!("abBA" => 0);
44 test_part_one!("abAB" => 4);
45 test_part_one!("aabAAB" => 6);
46
47 test_part_two!("dabAcCaCBAcCcaDA" => 4);
48
49 let input = include_str!("day05_input.txt");
50 test_part_one!(input => 11252);
51 test_part_two!(input => 6118);
52}