day 15
This commit is contained in:
parent
e9ee2c7ac7
commit
9cdcdc1208
47
day15/part1.lua
Executable file
47
day15/part1.lua
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
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 pq = pqueue(function(a, b)
|
||||||
|
return a[3] < b[3]
|
||||||
|
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
|
||||||
|
local r, c, d = unpack(n)
|
||||||
|
if 0 < r or r <= #grid or 0 < c or c <= #grid[r] then
|
||||||
|
local row = distances[r] or {}
|
||||||
|
if d < (row[c] or H) 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) })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
n = pq:pop()
|
||||||
|
end
|
||||||
|
|
||||||
|
print(distances[#grid] and distances[#grid][#grid[1]])
|
60
day15/part2.lua
Executable file
60
day15/part2.lua
Executable file
@ -0,0 +1,60 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local pq = pqueue(function(a, b)
|
||||||
|
return a[3] < b[3]
|
||||||
|
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
|
||||||
|
local r, c, d = unpack(n)
|
||||||
|
if 0 < r or r <= #grid or 0 < c or c <= #grid[r] then
|
||||||
|
local row = distances[r] or {}
|
||||||
|
if d < (row[c] or H) 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) })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
n = pq:pop()
|
||||||
|
end
|
||||||
|
|
||||||
|
print(distances[#grid] and distances[#grid][#grid[1]])
|
49
pqueue.lua
Normal file
49
pqueue.lua
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
local function add(self, item)
|
||||||
|
table.insert(self.items, item)
|
||||||
|
local i, p = #self.items
|
||||||
|
local p = math.floor(i / 2)
|
||||||
|
while i > 1 and self.smaller(self.items[i], self.items[p]) do
|
||||||
|
self.items[p], self.items[i] = self.items[i], self.items[p]
|
||||||
|
i, p = p, math.floor(p / 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pop(self)
|
||||||
|
local item = self.items[1]
|
||||||
|
self.items[1] = self.items[#self.items]
|
||||||
|
table.remove(self.items)
|
||||||
|
local i = 1
|
||||||
|
while i * 2 <= #self.items do
|
||||||
|
if i * 2 + 1 <= #self.items then
|
||||||
|
if self.smaller(self.items[i*2], self.items[i])
|
||||||
|
or self.smaller(self.items[i*2+1], self.items[i]) then
|
||||||
|
if self.smaller(self.items[i*2], self.items[i*2+1]) then
|
||||||
|
self.items[i], self.items[i*2], i
|
||||||
|
= self.items[i * 2], self.items[i], i * 2
|
||||||
|
else
|
||||||
|
self.items[i], self.items[i*2+1], i
|
||||||
|
= self.items[i*2+1], self.items[i], i * 2 + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if self.smaller(self.items[i*2], self.items[i]) then
|
||||||
|
self.items[i], self.items[i * 2]
|
||||||
|
= self.items[i * 2], self.items[i]
|
||||||
|
end
|
||||||
|
i = i * 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return item
|
||||||
|
end
|
||||||
|
|
||||||
|
function pqueue(smaller)
|
||||||
|
return {
|
||||||
|
items = {},
|
||||||
|
smaller = smaller
|
||||||
|
or function(a, b) return a < b end,
|
||||||
|
add = add,
|
||||||
|
pop = pop,
|
||||||
|
}
|
||||||
|
end
|
13
utils.lua
13
utils.lua
@ -24,12 +24,21 @@ function foreach(t, f)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function printtable(t)
|
function printtable(t, nonewline)
|
||||||
for k, v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
io.write(k..":"..v.." ")
|
io.write(k..":")
|
||||||
|
if type(v) == "table" then
|
||||||
|
io.write("(")
|
||||||
|
printtable(v, true)
|
||||||
|
io.write(") ")
|
||||||
|
else
|
||||||
|
io.write(v.." ")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
if not nonewline then
|
||||||
io.write("\n")
|
io.write("\n")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function count(t, pred)
|
function count(t, pred)
|
||||||
local count = 0
|
local count = 0
|
||||||
|
Loading…
Reference in New Issue
Block a user