adventofcode-2021/day15/part2.lua

49 lines
1.2 KiB
Lua
Executable File

#!/usr/bin/env luajit
require("utils")
require("pqueue")
local grid = {}
for line in io.lines(arg[3]) do
local row = {}
for char in chars(line) do
table.insert(row, tonumber(char))
end
table.insert(grid, row)
end
local h, w = #grid, #grid[1]
local function cost(r, c)
if r <= 0 or c <= 0 or r > 5 * h or c > 5 * w then
return math.huge
else
return (grid[(r-1)%h+1][(c-1)%w+1]
+ math.floor((r-1)/h)
+ math.floor((c-1)/w)
- 1
) % 9 + 1
end
end
local pq = pqueue(function(a, b)
return a[3] < b[3]
end)
local distances = {}
local n = { 1, 1, 0 }
while n ~= nil and (distances[5*h] == nil or distances[5*h][5*w] == nil) do
local r, c, d = unpack(n)
local row = distances[r] or {}
if d < (row[c] or math.huge) then
row[c] = d
distances[r] = row
if cost(r-1, c) < math.huge then pq:add({ r-1, c, d + cost(r-1, c) }) end
if cost(r, c-1) < math.huge then pq:add({ r, c-1, d + cost(r, c-1) }) end
if cost(r+1, c) < math.huge then pq:add({ r+1, c, d + cost(r+1, c) }) end
if cost(r, c+1) < math.huge then pq:add({ r, c+1, d + cost(r, c+1) }) end
end
n = pq:pop()
end
print(distances[5*h] and distances[5*h][5*w])