Advent of Code 2019 - Lua
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.0 KiB

width = nil
map = {}
for line in io.lines(arg[1]) do
if not width then
width = #line
end
for char in line:gmatch(".") do
table.insert(map, char)
end
end
function reachable_keys(map, pos_y, pos_x, keys, dist)
local cell = map[width * pos_y + pos_x]
if cell == "@" then
cell = "."
end
if cell == "." then
map[width * pos_y + pos_x] = "#"
reachable_keys(map, pos_y + 1, pos_x, keys, dist + 1)
reachable_keys(map, pos_y - 1, pos_x, keys, dist + 1)
reachable_keys(map, pos_y, pos_x + 1, keys, dist + 1)
reachable_keys(map, pos_y, pos_x - 1, keys, dist + 1)
elseif string.byte(cell) >= 97 and string.byte(cell) <= 122 then
table.insert(keys, {key=cell, y=pos_y, x=pos_x, dist=dist})
end
return keys
end
function find_paths(map, pos_y, pos_x)
local keys = reachable_keys({table.unpack(map)}, pos_y, pos_x, {}, 0)
local paths = {}
for _, key in ipairs(keys) do
--print(key.key, key.dist)
local open_map = {table.unpack(map)}
open_map[width * pos_y + pos_x] = "."
open_map[width * key.y + key.x] = "@"
for i, x in ipairs(open_map) do
if x:lower() == key.key then
open_map[i] = "."
break
end
end
local path = find_paths(open_map, key.y, key.x)
if #path == 0 then
table.insert(paths, {path={key.key}, dist=key.dist})
else
for _, p in ipairs(path) do
table.insert(p.path, key.key)
p.dist = p.dist + key.dist
table.insert(paths, p)
end
end
end
return paths
end
pos_y = nil
pos_x = nil
for i, x in ipairs(map) do
if x == "@" then
pos_y = i // width
pos_x = i % width
break
end
end
paths = find_paths(map, pos_y, pos_x)
smallest = nil
for _, path in ipairs(paths) do
if not smallest or smallest.dist > path.dist then
smallest = path
end
end
print(table.concat(smallest.path, ","), smallest.dist)