advent-of-code/12022/12/12.lua

97 lines
2.2 KiB
Lua

--io.input("test")
io.input("input")
function loc(x, y)
return { x = x, y = y }
end
local map = { v = {} }
-- parsing
local start, dest
local row = 1
local w, h
for line in io.lines() do
if row==1 then w = #line end
local col = 1
map[row] = {}
map.v[row] = {}
for h in string.gmatch(line,"%a") do
local height = string.byte(h)
if h=='S' then
height = string.byte('a')
start = loc( col, row )
elseif h=='E' then
height = string.byte('z')
dest = loc( col, row )
end
map[row][col] = height
map.v[row][col] = false -- visited
col = col + 1
end
row = row + 1
end
map.cols = w
map.rows = row-1
function map:nextMoves( x, y )
local map = self
local cur = map[y][x]
local leftDif = x>1 and not map.v[y][x-1] and cur-map[y][x-1]<=1
local rightDif = x<map.cols and not map.v[y][x+1] and cur-map[y][x+1]<=1
local upDif = y>1 and not map.v[y-1][x] and cur-map[y-1][x]<=1
local downDif = y<map.rows and not map.v[y+1][x] and cur-map[y+1][x]<=1
local moves = {}
if leftDif then table.insert( moves, loc( x-1, y) ) end
if rightDif then table.insert( moves, loc( x+1, y) ) end
if upDif then table.insert( moves, loc( x, y-1) ) end
if downDif then table.insert( moves, loc( x, y+1) ) end
return moves
end
local tocheck = { loc(dest.x, dest.y) }
map.v[dest.y][dest.x] = true -- visited
local count = 1
local count2
repeat
local checking = {}
for _, p in ipairs(tocheck) do
table.insert( checking, p )
end
tocheck = {}
local found = false
for _, p in ipairs(checking) do
map.v[p.y][p.x] = true
local t = map:nextMoves( p.x, p.y )
for _, move in ipairs(t) do
-- insert move only if not there already
local contains = false
for _, m in ipairs(tocheck) do
if m.x==move.x and m.y==move.y then
contains = true
break
end
end
if not contains then table.insert( tocheck, move ) end
-- part 1
if move.x == start.x and move.y == start.y then
found = true
end
-- part2
if not count2 and map[move.y][move.x]==string.byte('a') then
count2 = count
end
end
end
if not found then count = count + 1 end
until found
print("part 1", count)
print("part 2", count2)