diff --git a/day15/part2.lua b/day15/part2.lua index ccec019..1a5acde 100755 --- a/day15/part2.lua +++ b/day15/part2.lua @@ -10,26 +10,17 @@ for line in io.lines(arg[3]) do end table.insert(grid, row) end - -function printgrid() - for r, row in pairs(grid) do - for c, cell in pairs(row) do - io.write(string.format("%3d", cell)) - end - io.write('\n') - end -end - local h, w = #grid, #grid[1] -for r0 = 0, 4 do - for c0 = 0, 4 do - for r = 1, h do - for c = 1, w do - local row = grid[r0*h + r] or {} - row[c0*w + c] = (grid[r][c] + r0 + c0 - 1) % 9 + 1 - grid[r0*h + r] = row - end - end + +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 @@ -39,22 +30,21 @@ end) local distances = {} -local H = math.huge local n = { 1, 1, 0 } -while n ~= nil and (distances[#grid] == nil or distances[#grid][#grid[1]] == nil) do +while n ~= nil and (distances[5*h] == nil or distances[5*h][5*w] == nil) do local r, c, d = unpack(n) - if 0 < r or r <= #grid or 0 < c or c <= #grid[r] then + if cost(r, c) < math.huge then local row = distances[r] or {} - if d < (row[c] or H) then + if d < (row[c] or math.huge) then row[c] = d distances[r] = row - pq:add({ r-1, c, d + ((grid[r-1] or {})[c] or H) }) - pq:add({ r, c-1, d + ((grid[r] or {})[c-1] or H) }) - pq:add({ r+1, c, d + ((grid[r+1] or {})[c] or H) }) - pq:add({ r, c+1, d + ((grid[r] or {})[c+1] or H) }) + pq:add({ r-1, c, d + cost(r-1, c) }) + pq:add({ r, c-1, d + cost(r, c-1) }) + pq:add({ r+1, c, d + cost(r+1, c) }) + pq:add({ r, c+1, d + cost(r, c+1) }) end end n = pq:pop() end -print(distances[#grid] and distances[#grid][#grid[1]]) +print(distances[5*h] and distances[5*h][5*w])