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,11 +24,20 @@ function foreach(t, f)
|
||||
end
|
||||
end
|
||||
|
||||
function printtable(t)
|
||||
function printtable(t, nonewline)
|
||||
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
|
||||
if not nonewline then
|
||||
io.write("\n")
|
||||
end
|
||||
end
|
||||
|
||||
function count(t, pred)
|
||||
|
Loading…
Reference in New Issue
Block a user