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
|
use advent_of_code::prelude::*;
fn process(polymer: &[u8], rules: &HashMap<Vec<u8>, u8>) -> Vec<u8> {
let mut insertions = vec![];
for (i, elements) in polymer.windows(2).enumerate() {
for (pattern, insert) in rules {
if pattern == elements {
insertions.push((i + 1, insert));
}
}
}
let mut polymer = polymer.to_vec();
for (idx, c) in insertions.iter().rev() {
polymer.insert(*idx, **c);
}
polymer
}
pub fn parse(fh: File) -> Result<(Vec<u8>, HashMap<Vec<u8>, u8>)> {
let mut lines = parse::raw_lines(fh);
let polymer = lines.next().unwrap();
lines.next();
let mut rules = HashMap::new();
for line in lines {
let rule: Vec<_> = line.split(" -> ").collect();
rules.insert(rule[0].as_bytes().to_vec(), rule[1].as_bytes()[0]);
}
Ok((polymer.as_bytes().to_vec(), rules))
}
pub fn part1(
(mut polymer, rules): (Vec<u8>, HashMap<Vec<u8>, u8>),
) -> Result<u64> {
for _ in 0..10 {
polymer = process(&polymer, &rules);
}
let mut elements = HashMap::new();
for element in polymer {
let count = elements.entry(element).or_insert(0);
*count += 1;
}
Ok(elements.values().max().unwrap() - elements.values().min().unwrap())
}
pub fn part2(
(polymer, rules): (Vec<u8>, HashMap<Vec<u8>, u8>),
) -> Result<u64> {
let mut pairs = HashMap::new();
for pair in polymer.windows(2) {
let count = pairs.entry([pair[0], pair[1]]).or_insert(0);
*count += 1;
}
for _ in 0..40 {
let mut next = HashMap::new();
for (pair, count) in &mut pairs {
let insert = rules[&pair[..]];
let new_pair1 = [pair[0], insert];
let new_pair2 = [insert, pair[1]];
let next_count = next.entry(new_pair1).or_insert(0);
*next_count += *count;
let next_count = next.entry(new_pair2).or_insert(0);
*next_count += *count;
}
pairs = next;
}
let mut elements = HashMap::new();
for (pair, count) in pairs {
let element_count = elements.entry(pair[0]).or_insert(0);
*element_count += count;
let element_count = elements.entry(pair[1]).or_insert(0);
*element_count += count;
}
let element_count = elements.entry(polymer[0]).or_insert(0);
*element_count += 1;
let element_count =
elements.entry(polymer[polymer.len() - 1]).or_insert(0);
*element_count += 1;
Ok(elements.values().max().unwrap() / 2
- elements.values().min().unwrap() / 2)
}
#[test]
fn test() {
assert_eq!(
part1(parse(parse::data(2021, 14).unwrap()).unwrap()).unwrap(),
2874
);
assert_eq!(
part2(parse(parse::data(2021, 14).unwrap()).unwrap()).unwrap(),
5208377027195
);
}
|