day 10, part 2!

This commit is contained in:
sejo 2023-12-10 12:06:25 +01:00
parent 6fa9d65e9e
commit 7b323d202b
1 changed files with 122 additions and 7 deletions

View File

@ -1,6 +1,5 @@
io.input("input")
function coord(j,i) return {["j"]=j, ["i"]=i} end
function same(c1, c2)
if c1 and c2 then return c1.j==c2.j and c1.i==c2.i end
@ -9,6 +8,8 @@ end
function visited(c) return map[c.j][c.i].steps>=0 end
function in_path(c) return map[c.j][c.i].nxt end
function two_connections(j, i) -- returns two coordinates of connected tiles
if j<1 or j>nrows or i<1 or i>ncols then
return nil,nil
@ -18,26 +19,36 @@ function two_connections(j, i) -- returns two coordinates of connected tiles
local c = tile.char
if c=="S" then --find
local matches = {}
local dirs = {}
local x, y = two_connections(j-1, i) -- north
if same(co,x) or same(co,y) then
print("N!")
dirs.N = true
table.insert(matches, coord(j-1, i))
end
x, y = two_connections(j+1, i) -- south
if same(co,x) or same(co,y) then
print("S!")
dirs.S = true
table.insert(matches, coord(j+1, i))
end
x, y = two_connections(j, i-1) -- west
if same(co,x) or same(co,y) then
print("W!")
dirs.W = true
table.insert(matches, coord(j, i-1))
end
x, y = two_connections(j, i+1) -- east
if same(co,x) or same(co,y) then
print("E!")
dirs.E = true
table.insert(matches, coord(j, i+1))
end
-- replaceS
if dirs.N and dirs.E then newS = "L"
elseif dirs.N and dirs.S then newS = "|"
elseif dirs.N and dirs.W then newS = "J"
elseif dirs.E and dirs.S then newS = "F"
elseif dirs.E and dirs.W then newS = "-"
elseif dirs.S and dirs.W then newS = "7"
end
map[j][i].char = newS
return table.unpack(matches)
elseif c=="|" then -- north and south
return coord(j-1,i), coord(j+1,i)
@ -78,25 +89,129 @@ for line in io.lines() do
j = j + 1
end
nrows = j-1
print(map[start.j][start.i].char, start.j, start.i)
--print(nrows, ncols)
--print(map[start.j][start.i].char, start.j, start.i)
checking = {start}
maxsteps = 0
firstF = start
repeat
check = table.remove(checking,1)
steps = map[check.j][check.i].steps
if steps>maxsteps then maxsteps=steps end
-- print(steps, "checking", check.j, check.i, map[check.j][check.i].char)
x, y = two_connections(check.j,check.i)
map[check.j][check.i].conns = table.pack(x,y)
if not visited(x) then
map[x.j][x.i].steps = steps+1
table.insert(checking,x)
if x.j<=firstF.j and x.i<=firstF.i then firstF = x end
end
if not visited(y) then
map[y.j][y.i].steps = steps+1
table.insert(checking,y)
if y.j<=firstF.j and y.i<=firstF.i then firstF = y end
end
-- print(map[x.j][x.i].char, map[y.j][y.i].char)
until #checking==0
print("part 1", maxsteps, steps)
--print(firstF.j, firstF.i, map[firstF.j][firstF.i].char)
check = firstF
x,y = table.unpack(map[check.j][check.i].conns)
if x.i==check.i+1 then -- next is x
n = x
else
n = y
end
-- create path
repeat
map[check.j][check.i].nxt = n
--print(n.j, n.i, map[n.j][n.i].char)
prev = check
check = n
local x,y = table.unpack(map[check.j][check.i].conns)
if x.i==prev.i and x.j==prev.j then -- next is y
n = y
else
n = x
end
until check.j==firstF.j and check.i == firstF.i
count = 0
for r=1,nrows do
for c=1,ncols do
--print("checking",r,c)
local check = coord(r,c)
local dirs = {}
if not visited(check) then
dirs.N = false
for j=r-1,1,-1 do
local coor = coord(j,c)
if visited(coor) then
local tile = map[coor.j][coor.i]
local n = tile.nxt
if (tile.char=="J" and n.j<j) or ((tile.char=="-" or tile.char=="L") and n.i>c) then
dirs.N = true
--print("N", r, c, j, c, tile.char, n.j, n.i, map[n.j][n.i].char)
end
break
end
end
dirs.S = false
for j=r+1,nrows do
local coor = coord(j,c)
if visited(coor) then
local tile = map[coor.j][coor.i]
local n = tile.nxt
if (tile.char=="F" and n.j>j) or ((tile.char=="-" or tile.char=="7") and n.i<c) then
dirs.S = true
--print("S", r, c, j, c, tile.char, n.j, n.i, map[n.j][n.i].char)
end
break
end
end
dirs.W = false
for i=c-1,1,-1 do
local coor = coord(r,i)
if visited(coor) then
local tile = map[coor.j][coor.i]
local n = tile.nxt
if (tile.char=="7" and n.i<i) or ((tile.char=="|" or tile.char=="J") and n.j<r) then
dirs.W = true
--print("W", r, c, r, i, tile.char, n.j, n.i, map[n.j][n.i].char)
end
break
end
end
dirs.E = false
for i=c+1,ncols do
local coor = coord(r,i)
if visited(coor) then
local tile = map[coor.j][coor.i]
local n = tile.nxt
if (tile.char=="L" and n.i>i) or ((tile.char=="|" or tile.char=="F") and n.j>r) then
dirs.E = true
--print("E", r, c, r, i, tile.char, n.j, n.i, map[n.j][n.i].char)
end
break
end
end
if dirs.N and dirs.S and dirs.E and dirs.W then
--print("inside!", r,c)
count = count+1
end
end
end
end
print("part 2", count)