-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday22.rs
executable file
·60 lines (53 loc) · 1.34 KB
/
day22.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
#![feature(iter_map_windows)]
use std::collections::HashMap;
use anyhow::Result;
use itertools::Itertools;
use rayon::prelude::*;
use rust_aoc_util::slurp_nums;
fn sim(mut n: u64) -> Vec<u64> {
let mut res = vec![n];
for _ in 0..2000 {
n = ((n << 6) ^ n) & 16777215;
n = ((n >> 5) ^ n) & 16777215;
n = ((n << 11) ^ n) & 16777215;
res.push(n);
}
res
}
type W4 = (i32, i32, i32, i32);
fn main() -> Result<()> {
let sims: Vec<Vec<u64>> = slurp_nums(&std::fs::read_to_string("../inputs/day22.txt")?)?
.iter()
.map(|n: &i32| sim(*n as u64))
.collect();
let one: u64 = sims.iter().map(|v| v[2000]).sum();
assert_eq!(13584398738, one);
println!("{one}");
let diffs: Vec<HashMap<W4, i32>> = sims
.par_iter()
.map(|v| v.iter().map(|n| n.rem_euclid(10) as i32).collect_vec())
.map(|v| {
v.iter()
.map_windows(|&[a, b]| *b - *a)
.tuple_windows::<W4>()
.enumerate()
.map(|(i, w)| (w, v[i + 4]))
.unique_by(|(w, _)| *w) // first window wins
.collect()
})
.collect();
let two = *diffs
.iter()
.fold(HashMap::new(), |mut acc, hm| {
for (w, &v) in hm {
acc.entry(w).and_modify(|ov| *ov += v).or_insert(v);
}
acc
})
.values()
.max()
.unwrap();
assert_eq!(1612, two);
println!("{two}");
Ok(())
}