97 lines
2.2 KiB
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)
|