Day 18
file:test/Day18Spec.jl
# add tests
file:src/Day18.jl
module Day18
using DataStructures
function grid_dijkstra(
::Type{T}, size::NTuple{Dim,Int},
::Vector{CartesianIndex{Dim}}, istarget::F1,
start::F2, dist_func::F3) where {T,Dim,F1,F2,F3}
neighbours
= falses(size...)
visited = fill(typemax(T), size)
distance = PriorityQueue{CartesianIndex{Dim},T}()
queue = Array{CartesianIndex{Dim},Dim}(undef, size)
prev
for s in start
= zero(T)
distance[s] enqueue!(queue, s, zero(T))
end
= nothing
current while !isempty(queue)
= dequeue!(queue)
current istarget(current) && return (distance=distance, route=prev, target=current)
&& continue
visited[current] for loc in neighbours(current)
&& continue
visited[loc] = distance[current] + dist_func(current, loc)
d if d < distance[loc]
= d
distance[loc] = current
prev[loc] = d
queue[loc] end
end
= true
visited[current] end
return nothing
end
const Pos = CartesianIndex{2}
function trace_back(prev, start, target)
= [target]
route = target
current while current != start
= prev[current]
current push!(route, current)
end
reverse(route)
end
function main(io::IO)
= readlines(open("data/day18.txt")) .|>
input x->CartesianIndex((parse.(Int, split(x,',')) .+ 1)...))
(
= zeros(Int, 71, 71)
m 1:1024]] .= 1
m[input[
is_target(p::Pos) = p == Pos(71, 71)
neighbours(p::Pos) =
filter(q->get(m, q, 1) == 0,
+ Pos(1, 0), p + Pos(0, 1),
[p + Pos(-1,0), p + Pos(0,-1)])
p dist_func(a::Pos, b::Pos) = sum(abs.(Tuple(a - b)))
= grid_dijkstra(Int, (71, 71), [Pos(1, 1)], is_target, neighbours, dist_func)
g
= g.distance[g.target]
part1
= nothing
part2 = trace_back(g.route, Pos(1, 1), Pos(71, 71))
tb = falses(71, 71)
tg .= true
tg[tb] for p in input[1025:end]
= 1
m[p] || continue
tg[p] = grid_dijkstra(Int, (71, 71), [Pos(1, 1)], is_target, neighbours, dist_func)
g if g === nothing
= p
part2 break
end
.= false
tg = trace_back(g.route, Pos(1, 1), Pos(71, 71))
tb .= true
tg[tb]
end
return part1, (part2[1]-1, part2[2]-1)
end
end