Skip to content

Commit be8fde5

Browse files
committed
Day 11
1 parent 44928a0 commit be8fde5

File tree

4 files changed

+123
-57
lines changed

4 files changed

+123
-57
lines changed

Cargo.lock

Lines changed: 92 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ chrono = { version = "0.4.38", optional = true }
2727
dhat = { version = "0.3.3", optional = true }
2828
heapless = "0.8.0"
2929
itertools = "0.13.0"
30+
memoize = "0.4.2"
3031
mygrid = { version = "0.0.1", path = "mygrid" }
3132
pico-args = "0.5.0"
3233
rayon = "1.10.0"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +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` |
24+
| [Day 11](./src/bin/11.rs) | `318.0ns` | `292.0ns` |
2525

26-
**Total: 14.61ms**
26+
**Total: 12.71ms**
2727
<!--- benchmarking table --->
2828

2929
---

src/bin/11.rs

Lines changed: 28 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,57 @@
1-
use rustc_hash::FxHashMap;
2-
3-
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
1+
use memoize::memoize;
42

53
advent_of_code::solution!(11);
64

75
type Stone = u64;
86
type Step = u8;
9-
type MemoKey = (Step, Stone);
10-
type Memo = FxHashMap<MemoKey, u64>;
117

12-
fn blink_rec(memo: &mut Memo, stone: Stone, times: Step) -> u64 {
8+
#[memoize]
9+
fn blink_rec(stone: Stone, times: Step) -> u64 {
1310
if times == 0 {
1411
return 1;
1512
}
16-
if let Some(count) = memo.get(&(times, stone)) {
17-
return *count;
18-
}
1913

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-
}
14+
if stone == 0 {
15+
return blink_rec(1, times - 1);
16+
}
17+
let mut digit_count = 0;
18+
let mut temp = stone;
19+
while temp > 0 {
20+
digit_count += 1;
21+
temp /= 10;
22+
}
2723

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-
};
24+
if digit_count % 2 == 0 {
25+
let divisor = 10_u64.pow(digit_count / 2);
26+
return blink_rec(stone / divisor, times - 1) + blink_rec(stone % divisor, times - 1);
27+
}
3828

39-
memo.insert((times, stone), res);
40-
res
29+
return blink_rec(stone * 2024, times - 1);
4130
}
4231

43-
fn parse_input(input: &str) -> Vec<Stone> {
44-
input
32+
fn solve(input: &str, times: Step) -> u64 {
33+
let stones = input
4534
.split_whitespace()
4635
.filter(|p| !p.is_empty())
4736
.map(|s| s.parse::<u64>())
4837
.filter(|r| r.is_ok())
4938
.map(|r| r.unwrap())
50-
.collect::<Vec<_>>()
51-
}
39+
.collect::<Vec<_>>();
5240

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());
5741
let count = stones
58-
.iter()
59-
.map(|start_stone| blink_rec(&mut memo, *start_stone, times))
42+
.iter() // so fast that parallel is slower
43+
.map(|start_stone| blink_rec(*start_stone, times))
6044
.sum::<u64>();
6145

62-
Some(count as u64)
46+
return count;
6347
}
6448

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>();
49+
pub fn part_one(input: &str) -> Option<u64> {
50+
Some(solve(input, 25))
51+
}
7552

76-
Some(count as u64)
53+
pub fn part_two(input: &str) -> Option<u64> {
54+
Some(solve(input, 75))
7755
}
7856

7957
#[cfg(test)]

0 commit comments

Comments
 (0)