day15 p2: proper Bellman-Ford
This commit is contained in:
113
day15/part2.jl
113
day15/part2.jl
@@ -171,10 +171,35 @@ function neighbor_idx(nrows, ncols, y, x)
|
||||
return v
|
||||
end
|
||||
|
||||
function relax(nrows, ncols, R, costs, row, col; first=false)
|
||||
idx = neighbor_idx(nrows, ncols, row, col)
|
||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
||||
if first || c < costs[row, col]
|
||||
costs[row, col] = c
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function relax_all(nrows, ncols, R, costs)
|
||||
relaxed = false
|
||||
for row in 1:nrows
|
||||
for col in 1:ncols
|
||||
v_relaxed = relax(nrows, ncols, R, costs, row, col)
|
||||
relaxed = relaxed || v_relaxed
|
||||
end
|
||||
end
|
||||
return relaxed
|
||||
end
|
||||
|
||||
function get_costs(R)
|
||||
costs = zeros(Int, size(R))
|
||||
dirs = zeros(Int, size(R))
|
||||
nrows, ncols = size(R)
|
||||
|
||||
# first pass, unconditional update looking only right/down. Avoids
|
||||
# having to add an infinity value
|
||||
costs[1,1] = 0
|
||||
for col in 2:ncols
|
||||
costs[1, col] = costs[1, col-1] + R[1, col]
|
||||
end
|
||||
@@ -190,90 +215,24 @@ function get_costs(R)
|
||||
end
|
||||
end
|
||||
|
||||
if false
|
||||
# more passes
|
||||
for i in 1:max(nrows, ncols)
|
||||
for col in ncols-1:-1:1
|
||||
rcost = costs[end, col+1] + R[end, col]
|
||||
if rcost < costs[end, col]
|
||||
costs[end, col] = rcost
|
||||
end
|
||||
end
|
||||
for row in nrows-1:-1:1
|
||||
dcost = costs[row+1, end] + R[row, end]
|
||||
if dcost < costs[row, end]
|
||||
costs[row, end] = dcost
|
||||
end
|
||||
for col in ncols-1:-1:1
|
||||
rcost = costs[row, col+1] + R[row, col]
|
||||
if rcost < costs[row, col]
|
||||
costs[row, col] = rcost
|
||||
end
|
||||
dcost = costs[row+1, col] + R[row, col]
|
||||
if dcost < costs[row, col]
|
||||
costs[row, col] = dcost
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
edges = ( (nrows-2)*(ncols-2)*4
|
||||
+(nrows+ncols-4)*3
|
||||
+4*2 )
|
||||
max_passes = (nrows*ncols - 1) * edges
|
||||
|
||||
for i in 1:max(nrows, ncols)
|
||||
|
||||
for row in nrows:-1:1
|
||||
for col in ncols:-1:1
|
||||
idx = neighbor_idx(nrows, ncols, row, col)
|
||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
||||
if c < costs[row, col]
|
||||
costs[row, col] = c
|
||||
i = 1
|
||||
while i <= max_passes
|
||||
relaxed = relax_all(nrows, ncols, R, costs)
|
||||
if !relaxed
|
||||
break
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
for row in nrows:-1:1
|
||||
for col in 1:ncols
|
||||
idx = neighbor_idx(nrows, ncols, row, col)
|
||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
||||
if c < costs[row, col]
|
||||
costs[row, col] = c
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for row in 1:nrows
|
||||
for col in ncols:-1:1
|
||||
idx = neighbor_idx(nrows, ncols, row, col)
|
||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
||||
if c < costs[row, col]
|
||||
costs[row, col] = c
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for row in 1:nrows
|
||||
for col in 1:ncols
|
||||
idx = neighbor_idx(nrows, ncols, row, col)
|
||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
||||
if c < costs[row, col]
|
||||
costs[row, col] = c
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
println("passes ", i)
|
||||
|
||||
return costs, dirs
|
||||
end
|
||||
|
||||
#=
|
||||
cost, path = least_risk(risk_map)
|
||||
|
||||
display(path)
|
||||
println()
|
||||
|
||||
println("cost = ", cost)
|
||||
=#
|
||||
|
||||
costs, dirs = get_costs(risk_map)
|
||||
|
||||
if length(costs) < 1000
|
||||
|
||||
Reference in New Issue
Block a user