-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
main.rs
53 lines (47 loc) · 1.54 KB
/
main.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
use std::mem;
pub fn main() {
let (base, rules) = include_str!("../input.txt").split_once("\n\n").unwrap();
let base = base.as_bytes().to_vec();
let mut rules = rules
.lines()
.map(|l| {
let (k, t) = l.split_once(" -> ").unwrap();
let (k, t) = (k.as_bytes(), t.as_bytes()[0]);
([k[0], k[1]], [k[0], t])
})
.collect::<Vec<_>>();
rules.sort_unstable_by_key(|r| r.0);
let rule = rules
.iter()
.map(|r| {
(
r.0,
rules.binary_search_by_key(&r.1, |r| r.0).unwrap(),
rules
.binary_search_by_key(&[r.1[1], r.0[1]], |r| r.0)
.unwrap(),
)
})
.collect::<Vec<_>>();
let (mut num, mut next) = (vec![0; rule.len()], vec![0; rule.len()]);
base.windows(2)
.for_each(|key| num[rule.binary_search_by_key(&key, |r| &r.0).unwrap()] += 1);
(0..40).for_each(|_| {
num.iter_mut().zip(&rule).for_each(|(n, r)| {
next[r.1] += *n;
next[r.2] += *n;
*n = 0;
});
mem::swap(&mut num, &mut next);
});
let mut occur = [0; (b'Z' - b'A') as usize];
occur[(base.last().unwrap() - b'A') as usize] += 1;
rule.iter()
.zip(num)
.for_each(|(r, n)| occur[(r.0[0] - b'A') as usize] += n);
let (min, max) = occur
.iter()
.filter(|&&n| n != 0)
.fold((u64::MAX, 0), |(min, max), &n| (min.min(n), max.max(n)));
println!("{}", max - min);
}