-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday11.rs
84 lines (74 loc) · 2.21 KB
/
day11.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use aoc_runner_derive::aoc;
#[aoc(day11, part1)]
#[must_use]
pub fn part1(input: &str) -> usize {
solve(&mut parse_input(input), 25)
}
#[aoc(day11, part2)]
#[must_use]
pub fn part2(input: &str) -> usize {
solve(&mut parse_input(input), 75)
}
fn parse_input(input: &str) -> rustc_hash::FxHashMap<usize, usize> {
input
.split_ascii_whitespace()
.map(|s| (s.parse().unwrap(), 1))
.collect()
}
fn solve(map: &mut rustc_hash::FxHashMap<usize, usize>, n_steps: u32) -> usize {
(0..n_steps).for_each(|_| {
map.clone()
.iter()
.filter(|(_, &value)| value != 0)
.for_each(|(&key, &value)| {
if key == 0 {
add(map, 1, value);
sub(map, key, value);
} else {
let str_key = key.to_string();
if str_key.len() % 2 == 0 {
let (key0, key1) = {
let key_len_half = str_key.len() / 2;
(
str_key[..key_len_half].parse().unwrap(),
str_key[key_len_half..].parse().unwrap(),
)
};
add(map, key0, value);
add(map, key1, value);
sub(map, key, value);
} else {
add(map, 2024 * key, value);
sub(map, key, value);
}
}
});
});
map.values().sum()
}
fn add(map: &mut rustc_hash::FxHashMap<usize, usize>, key: usize, value: usize) {
if let Some(key) = map.get_mut(&key) {
*key += value;
} else {
map.insert(key, value);
}
}
fn sub(map: &mut rustc_hash::FxHashMap<usize, usize>, key: usize, value: usize) {
*map.get_mut(&key).unwrap() -= value;
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
const SAMPLE: &str = indoc! {"
125 17
"};
#[test]
pub fn part1_example() {
assert_eq!(part1(SAMPLE), 55_312);
}
#[test]
pub fn part2_example() {
assert_eq!(part2(SAMPLE), 65_601_038_650_482);
}
}