-
Notifications
You must be signed in to change notification settings - Fork 0
/
14.rs
65 lines (57 loc) · 1.68 KB
/
14.rs
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
#![feature(test)]
use counter::Counter;
use regex::Regex;
use rustc_hash::FxHashMap;
struct Input {
template: String,
rules: FxHashMap<(char, char), char>,
}
fn setup(input: &str) -> Input {
let mut lines = input.lines();
let template = lines.next().unwrap().to_string();
lines.next();
let regex = Regex::new(r"^([A-Z])([A-Z]) -> ([A-Z])$").unwrap();
let rules = lines
.map(|line| {
let capture = regex.captures(line).unwrap();
let get = |i| capture.get(i).unwrap().as_str().chars().next().unwrap();
((get(1), get(2)), get(3))
})
.collect();
Input { template, rules }
}
fn solve(input: &Input, n: usize) -> usize {
let mut adj: Counter<(char, char)> = input
.template
.chars()
.zip(input.template[1..].chars())
.collect();
for _ in 0..n {
let mut new: Counter<(char, char)> = Counter::new();
for ((a, b), c) in adj.iter().map(|((a, b), c)| ((*a, *b), *c)) {
match input.rules.get(&(a, b)).cloned() {
None => {
new[&(a, b)] += c;
}
Some(x) => {
new[&(a, x)] += c;
new[&(x, b)] += c;
}
}
}
adj = new;
}
let mut chars = Counter::new();
chars[&input.template.chars().next().unwrap()] = 1;
for ((_, b), c) in &adj {
chars[b] += *c;
}
chars.values().max().unwrap() - chars.values().min().unwrap()
}
fn part1(input: &Input) -> String {
solve(input, 10).to_string()
}
fn part2(input: &Input) -> String {
solve(input, 40).to_string()
}
aoc::main!(2021, 14, ex: 1);