This commit is contained in:
Felix Van der Jeugt 2021-12-15 10:51:53 +01:00
parent e9ee2c7ac7
commit 9cdcdc1208
No known key found for this signature in database
GPG Key ID: 58B209295023754D
4 changed files with 168 additions and 3 deletions

47
day15/part1.lua Executable file
View 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
View 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
View 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

View File

@ -24,11 +24,20 @@ 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)