73 lines
1.6 KiB
Python
73 lines
1.6 KiB
Python
import sys
|
|
from collections import defaultdict
|
|
map = [list(x.strip()) for x in sys.stdin]
|
|
|
|
print(map)
|
|
|
|
Y = len(map)
|
|
X = len(map[0])
|
|
assert all(len(row) == X for row in map)
|
|
|
|
N,E,S,W = 1,2,4,8
|
|
unknown = 0b11111
|
|
grid = {}
|
|
start = None
|
|
for i, row in enumerate(map):
|
|
for j,c in enumerate(row):
|
|
d = 0
|
|
if c == ".": d = 0
|
|
elif c == "7": d = W|S
|
|
elif c == "J": d = N|W
|
|
elif c == "L": d = N|E
|
|
elif c == "F": d = S|E
|
|
elif c == "|": d = N|S
|
|
elif c == "-": d = W|E
|
|
elif c == "S":
|
|
d = unknown
|
|
start = (i,j)
|
|
else:
|
|
raise Exception("invalid char %s at (%s,%s)" % (c, i, j))
|
|
grid[i,j] = d
|
|
|
|
print(grid)
|
|
|
|
|
|
def find_loop(grid, start):
|
|
front = [(0,start)]
|
|
dist = {}
|
|
count = defaultdict(int)
|
|
count[start] -= 1
|
|
def push(i,j,from_):
|
|
if grid.get((i,j),0)&from_:
|
|
front.append((cost+1, (i,j)))
|
|
while front:
|
|
front.sort()
|
|
cost, n = front.pop(0)
|
|
if n not in grid:
|
|
continue
|
|
count[n] += 1
|
|
if n in dist:
|
|
continue
|
|
dist[n] = cost
|
|
i, j = n
|
|
d = grid[n]
|
|
if d&N: push(i-1,j,S)
|
|
if d&S: push(i+1,j,N)
|
|
if d&W: push(i,j-1,E)
|
|
if d&E: push(i,j+1,W)
|
|
|
|
#print(count.values())
|
|
if not all(c == 2 for c in count.values()):
|
|
# not a loop
|
|
return {}
|
|
|
|
return dist
|
|
|
|
for D in [W|S, N|W, N|E, S|E, N|S, W|E]:
|
|
grid[start] = D
|
|
loop = find_loop(grid, start)
|
|
if loop:
|
|
print(D, loop)
|
|
print(max(loop.values()))
|
|
|