Skip to content

Commit d17cc7d

Browse files
committed
[Day 11] Optimize
1 parent 56728ce commit d17cc7d

File tree

2 files changed

+63
-42
lines changed

2 files changed

+63
-42
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ This Julia package contains my solutions for [Advent of Code 2024](https://adven
2020
| 8 | [:white_check_mark:](https://adventofcode.com/2024/day/8) | Grid | Line Tracing, Grid Traversal | 94.050 μs | 46.30 KiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day08.jl) |
2121
| 9 | [:white_check_mark:](https://adventofcode.com/2024/day/9) | Array manipulation | Greedy | 28.311 ms | 9.58 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day09.jl) |
2222
| 10 | [:white_check_mark:](https://adventofcode.com/2024/day/10) | Grid | Recursion, DFS | 578.868 μs | 633.67 KiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day10.jl) |
23-
| 11 | [:white_check_mark:](https://adventofcode.com/2024/day/11) | Simulation | Dynamic Programming, Memoization | 15.667 ms | 12.60 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day11.jl) |
23+
| 11 | [:white_check_mark:](https://adventofcode.com/2024/day/11) | Simulation | Dynamic Programming, Memoization | 12.151 ms | 11.45 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day11.jl) |
2424
| 12 | [:white_check_mark:](https://adventofcode.com/2024/day/12) | Grid | DFS | 4.995 ms | 5.97 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day12.jl) |
2525
| 13 | [:white_check_mark:](https://adventofcode.com/2024/day/13) | Linear Algebra | Linear Systems | 3.101 ms | 1.15 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day13.jl) |
2626
| 14 | [:white_check_mark:](https://adventofcode.com/2024/day/14) | Simulation | Brute Force | 26.443 ms | 274.98 KiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day14.jl) |

src/day11.jl

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,76 @@ using AdventOfCode2024
44

55
function day11(input::String = readInput(joinpath(@__DIR__, "..", "data", "day11.txt")))
66
data = parse.(Int, split(rstrip(input)))
7-
return [solve(data, 25), solve(data, 75)]
8-
end
9-
10-
function solve(data, runtime)
7+
runtime1 = 25
8+
runtime2 = 75
9+
1110
lookup = Dict{Int,Tuple{Int,Int}}()
1211
lookup[0] = (1, -1)
13-
stones = Dict{Int,Dict{Int,Int}}()
14-
for i 0:runtime
15-
stones[i] = Dict{Int,Int}()
12+
13+
stones = Vector{Dict{Int,Int}}(undef, runtime2 + 1)
14+
for i in 0:runtime2
15+
stones[i+1] = Dict{Int,Int}()
1616
end
17-
for value data
18-
stones[runtime][value] = 1
17+
18+
result1 = compute_stones!(stones, data, runtime1, lookup)
19+
result2 = continue_stones!(stones, runtime1, runtime2, lookup)
20+
21+
return [result1, result2]
22+
end
23+
24+
function compute_stones!(stones, data, runtime, lookup)
25+
for value in data
26+
stones[runtime+1][value] = get!(stones[runtime+1], value, 0) + 1
1927
end
20-
@inbounds for rt runtime:-1:1
21-
for stone keys(stones[rt])
22-
if haskey(lookup, stone)
23-
l, r = lookup[stone]
24-
else
25-
if iseven(length(digits(stone)))
26-
l, r = split_number(stone)
27-
else
28-
l, r = stone * 2024, -1
29-
end
30-
lookup[stone] = (l, r)
31-
end
32-
amount = stones[rt][stone]
33-
if haskey(stones[rt-1], l)
34-
stones[rt-1][l] += amount
35-
else
36-
stones[rt-1][l] = amount
37-
end
38-
r == -1 && continue
39-
if haskey(stones[rt-1], r)
40-
stones[rt-1][r] += amount
41-
else
42-
stones[rt-1][r] = amount
43-
end
28+
29+
@inbounds for rt in runtime:-1:1
30+
current = stones[rt+1]
31+
next = stones[rt]
32+
for stone in keys(current)
33+
l, r = get_transformation(stone, lookup)
34+
amount = current[stone]
35+
next[l] = get!(next, l, 0) + amount
36+
r != -1 && (next[r] = get!(next, r, 0) + amount)
4437
end
4538
end
46-
return stones[0] |> values |> sum
39+
40+
return sum(values(stones[1]))
41+
end
4742

43+
function continue_stones!(stones, start_runtime, target_runtime, lookup)
44+
remaining = target_runtime - start_runtime
45+
stones[remaining+1] = copy(stones[1])
46+
# Clear intermediate levels
47+
for i in 1:remaining
48+
empty!(stones[i])
49+
end
50+
51+
@inbounds for rt in remaining:-1:1
52+
current = stones[rt+1]
53+
next = stones[rt]
54+
for stone in keys(current)
55+
l, r = get_transformation(stone, lookup)
56+
amount = current[stone]
57+
next[l] = get!(next, l, 0) + amount
58+
r != -1 && (next[r] = get!(next, r, 0) + amount)
59+
end
60+
end
61+
62+
return sum(values(stones[1]))
4863
end
4964

50-
function split_number(number::Int)
51-
digs = digits(number)
52-
n = length(digs)
53-
l = @view(digs[n÷2+1:end]) .* [10^x for x 0:n÷2-1] |> sum
54-
r = @view(digs[1:n÷2]) .* [10^x for x 0:n÷2-1] |> sum
55-
return l, r
65+
@inline function get_transformation(stone, lookup)
66+
return get!(lookup, stone) do
67+
digs = digits(stone)
68+
n = length(digs)
69+
if iseven(n)
70+
l = sum(@view(digs[n÷2+1:end]) .* [10^x for x 0:n÷2-1])
71+
r = sum(@view(digs[1:n÷2]) .* [10^x for x 0:n÷2-1])
72+
(l, r)
73+
else
74+
(stone * 2024, -1)
75+
end
76+
end
5677
end
5778

58-
end # module
79+
end # module

0 commit comments

Comments
 (0)