Skip to content

Commit

Permalink
[Day 21] Improve performance by a huge margin
Browse files Browse the repository at this point in the history
  • Loading branch information
goggle committed Jan 8, 2024
1 parent 257375f commit a3a0ab6
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 37 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ This Julia package contains my solutions for [Advent of Code 2023](https://adven
| 18 | [:white_check_mark:](https://adventofcode.com/2023/day/18) | 630.330 μs | 484.14 KiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day18.jl) |
| 19 | [:white_check_mark:](https://adventofcode.com/2023/day/19) | 2.559 ms | 1.79 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day19.jl) |
| 20 | [:white_check_mark:](https://adventofcode.com/2023/day/20) | 65.710 ms | 28.76 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day20.jl) |
| 21 | [:white_check_mark:](https://adventofcode.com/2023/day/21) | 146.688 ms | 185.76 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day21.jl) |
| 21 | [:white_check_mark:](https://adventofcode.com/2023/day/21) | 9.675 ms | 7.19 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day21.jl) |
| 22 | [:white_check_mark:](https://adventofcode.com/2023/day/22) | 790.712 ms | 631.26 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day22.jl) |
| 23 | [:white_check_mark:](https://adventofcode.com/2023/day/23) | 2.979 s | 9.69 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day23.jl) |
| 24 | [:white_check_mark:](https://adventofcode.com/2023/day/24) | 41.181 ms | 49.71 MiB | [:white_check_mark:](https://github.com/goggle/AdventOfCode2023.jl/blob/master/src/day24.jl) |
Expand Down
73 changes: 37 additions & 36 deletions src/day21.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module Day21

using AdventOfCode2023

using DataStructures

function day21(input::String = readInput(joinpath(@__DIR__, "..", "data", "day21.txt")))
data = map(x -> x[1], reduce(vcat, permutedims.(map(x -> split(x, ""), split(input)))))
start = findfirst(x -> x == 'S', data)
Expand All @@ -10,37 +12,49 @@ function day21(input::String = readInput(joinpath(@__DIR__, "..", "data", "day21
return [part1(M, start), part2(M, start)]
end

function part1(M::Matrix{Int8}, start::CartesianIndex{2}; nsteps::Int = 64)
M = copy(M)
M[start] = 1
for _ 1:nsteps
step!(M)
function part1(M::Matrix{Int8}, start::CartesianIndex{2})
visited = zeros(Bool, size(M))
visited[start] = true
return bfs!(copy(M), visited, [start], start, 64)[1]
end

dist(a::CartesianIndex{2}, b::CartesianIndex{2}) = abs.((a - b).I) |> sum

function bfs!(M::Matrix{Int8}, visited::Matrix{Bool}, queue::Vector{CartesianIndex{2}}, start::CartesianIndex{2}, nsteps::Int)
dirs = CartesianIndex.((1,0,-1,0), (0,1,0,-1))
conqueue = Vector{CartesianIndex{2}}()
while !isempty(queue)
pos = popfirst!(queue)
M[pos] = 1
for dir dirs
cand = pos + dir
if checkbounds(Bool, M, cand) && !visited[cand] && M[cand] == 0
if dist(start, cand) <= nsteps
push!(queue, cand)
visited[cand] = true
else
push!(conqueue, cand)
end
end
end
end
return sum(x -> x > 0, M)
parity = nsteps % 2
return [dist(pos, start) % 2 == parity for pos findall(x -> x == 1, M)] |> sum, conqueue
end

function part2(M::Matrix{Int8}, start::CartesianIndex{2})
MM = copy(M)
MM[start] = 1
start = CartesianIndex(start[1] + 2 * 131, start[2] + 2 * 131)
bigM = [M M M M M ;
M M M M M ;
M M MM M M ;
M M M M M ;
M M M M M ;
M M M M M ]

reachables = Int[]
for _ 1:65
step!(bigM)
end
push!(reachables, findall(x -> x == 1, bigM) |> length)
for _ 1:131
step!(bigM)
end
push!(reachables, findall(x -> x == 1, bigM) |> length)
for _ 1:131
step!(bigM)
end
push!(reachables, findall(x -> x == 1, bigM) |> length)
reachables = Int[0, 0, 0]
visited = zeros(Bool, size(bigM))
visited[start] = true
reachables[1], queue = bfs!(bigM, visited, [start], start, 65)
reachables[2], queue = bfs!(bigM, visited, queue, start, 196)
reachables[3], _ = bfs!(bigM, visited, queue, start, 327)

# Some explanations:
#
Expand Down Expand Up @@ -69,17 +83,4 @@ function part2(M::Matrix{Int8}, start::CartesianIndex{2})
return Int(p(Int64(202300)))
end

function step!(data::Matrix{Int8})
positions = findall(x -> x == 1, data)
data[positions] .= 0
dirs = CartesianIndex.((1,0,-1,0), (0,1,0,-1))
for pos positions
for dir dirs
if data[pos + dir] != -1
data[pos + dir] = 1
end
end
end
end

end # module

0 comments on commit a3a0ab6

Please sign in to comment.