Skip to content

Commit 5caaa76

Browse files
committed
Day 11
1 parent b40d162 commit 5caaa76

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
2121
| [Day 8](./src/bin/08.rs) | `7.4µs` | `15.5µs` |
2222
| [Day 9](./src/bin/09.rs) | `149.0µs` | `6.5ms` |
2323
| [Day 10](./src/bin/10.rs) | `31.1µs` | `28.6µs` |
24+
| [Day 11](./src/bin/11.rs) | `104.4µs` | `1.8ms` |
2425

25-
**Total: 12.71ms**
26+
**Total: 14.61ms**
2627
<!--- benchmarking table --->
2728

2829
---

data/examples/11.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
125 17

src/bin/11.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use rustc_hash::FxHashMap;
2+
3+
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
4+
5+
advent_of_code::solution!(11);
6+
7+
type Stone = u64;
8+
type Step = u8;
9+
type MemoKey = (Step, Stone);
10+
type Memo = FxHashMap<MemoKey, u64>;
11+
12+
fn blink_rec(memo: &mut Memo, stone: Stone, times: Step) -> u64 {
13+
if times == 0 {
14+
return 1;
15+
}
16+
if let Some(count) = memo.get(&(times, stone)) {
17+
return *count;
18+
}
19+
20+
let res = {
21+
let mut digit_count = 0;
22+
let mut temp = stone;
23+
while temp > 0 {
24+
digit_count += 1;
25+
temp /= 10;
26+
}
27+
28+
if stone == 0 {
29+
blink_rec(memo, 1, times - 1)
30+
} else if digit_count % 2 == 0 {
31+
let divisor = 10_u64.pow(digit_count / 2);
32+
blink_rec(memo, stone / divisor, times - 1)
33+
+ blink_rec(memo, stone % divisor, times - 1)
34+
} else {
35+
blink_rec(memo, stone * 2024, times - 1)
36+
}
37+
};
38+
39+
memo.insert((times, stone), res);
40+
res
41+
}
42+
43+
fn parse_input(input: &str) -> Vec<Stone> {
44+
input
45+
.split_whitespace()
46+
.filter(|p| !p.is_empty())
47+
.map(|s| s.parse::<u64>())
48+
.filter(|r| r.is_ok())
49+
.map(|r| r.unwrap())
50+
.collect::<Vec<_>>()
51+
}
52+
53+
pub fn part_one(input: &str) -> Option<u64> {
54+
let times = 25;
55+
let stones = parse_input(input);
56+
let mut memo = FxHashMap::with_capacity_and_hasher(100000, Default::default());
57+
let count = stones
58+
.iter()
59+
.map(|start_stone| blink_rec(&mut memo, *start_stone, times))
60+
.sum::<u64>();
61+
62+
Some(count as u64)
63+
}
64+
65+
pub fn part_two(input: &str) -> Option<u64> {
66+
let times = 75;
67+
let stones = parse_input(input);
68+
let count = stones
69+
.par_iter()
70+
.map(|start_stone| {
71+
let mut memo = FxHashMap::with_capacity_and_hasher(100000, Default::default());
72+
blink_rec(&mut memo, *start_stone, times)
73+
})
74+
.sum::<u64>();
75+
76+
Some(count as u64)
77+
}
78+
79+
#[cfg(test)]
80+
mod tests {
81+
use super::*;
82+
83+
// #[test]
84+
// fn test_part_one() {
85+
// let result = part_one("125");
86+
// assert_eq!(result, Some(55312));
87+
// }
88+
89+
#[test]
90+
fn test_part_one() {
91+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
92+
assert_eq!(result, Some(55312));
93+
}
94+
95+
#[test]
96+
fn test_part_two() {
97+
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
98+
assert_eq!(result, None);
99+
}
100+
}

0 commit comments

Comments
 (0)