115 lines
2.6 KiB
Python
115 lines
2.6 KiB
Python
|
import sys, os
|
||
|
from collections import Counter as C
|
||
|
from collections import defaultdict as dd
|
||
|
|
||
|
"""
|
||
|
same convention as SVG
|
||
|
W
|
||
|
(0,0)┌───────────► x
|
||
|
│
|
||
|
H │
|
||
|
│
|
||
|
│
|
||
|
▼
|
||
|
y
|
||
|
grid G store list of rows
|
||
|
to get G(x,y), must first extract row y and then col y => G[y][x]
|
||
|
"""
|
||
|
|
||
|
def grid_geom(G):
|
||
|
H = len(G)
|
||
|
W = len(G[0])
|
||
|
return W, H
|
||
|
|
||
|
def in_grid(G, x, y) -> bool:
|
||
|
W, H = grid_geom(G)
|
||
|
return x>=0 and x<W and y>=0 and y<H
|
||
|
|
||
|
def get_in_grid(G, x, y):
|
||
|
if in_grid(W, H, x,y):
|
||
|
return G[y][x]
|
||
|
|
||
|
UP = (0,-1) ; RIGHT = (1,0) ; DOWN = (0,1) ; LEFT = (-1,0)
|
||
|
M4=[ UP, RIGHT, DOWN, LEFT ]
|
||
|
D4 = [(1,1),(-1,-1),(1,-1),(-1,1)]
|
||
|
M8 = M4 + D4
|
||
|
|
||
|
L = sys.stdin.read().strip().split("\n")
|
||
|
G = [list(l) for l in L]
|
||
|
|
||
|
W, H = grid_geom(G)
|
||
|
|
||
|
# 1: find guard
|
||
|
gx = gy = 0
|
||
|
for i in range(H): # rows
|
||
|
for j in range(W): # cols
|
||
|
if G[i][j] == '^':
|
||
|
gx = j
|
||
|
gy = i
|
||
|
|
||
|
# 2: compute guard's walk
|
||
|
M4N = { M4[i-1]:M4[i] for i in range(len(M4))}
|
||
|
print(f'{M4N=}')
|
||
|
S = 0
|
||
|
V = C() # visited
|
||
|
T = dd(set) # each position forcing a turn, grouped by turn type
|
||
|
sens = M4[0]
|
||
|
on = True
|
||
|
while on : # in the map
|
||
|
V[(gx,gy)] +=1
|
||
|
(dx,dy) = sens
|
||
|
gxn = gx + dx
|
||
|
gyn = gy + dy
|
||
|
#print(S, sens, dx, dy, gxn, gyn)
|
||
|
if not in_grid(G, gxn, gyn): # off the map
|
||
|
on = False
|
||
|
elif G[gyn][gxn] == '#': # must turn
|
||
|
T[sens].add((gxn,gyn))
|
||
|
sens = M4N[sens]
|
||
|
else: # move
|
||
|
gx = gxn
|
||
|
gy = gyn
|
||
|
S += 1
|
||
|
print(S, len(V))
|
||
|
|
||
|
for (x,y) in V.keys():
|
||
|
G[y][x] = "o"
|
||
|
for row in G:
|
||
|
#print(" ".join(row))
|
||
|
pass
|
||
|
|
||
|
M = 0
|
||
|
for m, v in T.items():
|
||
|
(dx,dy) = m
|
||
|
for (x,y) in v:
|
||
|
print(f"{dx},{dy}:for", (x,y))
|
||
|
# find a position for nearest next turn
|
||
|
n = None
|
||
|
(dxn, dyn) = M4N[m]
|
||
|
for i in range(1,10):
|
||
|
cn = (x-dx+i*dxn,y-dy+i*dyn)
|
||
|
#print(f'{cn=}')
|
||
|
if cn in T[M4N[m]]:
|
||
|
n = cn
|
||
|
print(" found n", n)
|
||
|
break
|
||
|
if n:
|
||
|
(xn,yn) = n
|
||
|
(dxp, dyp) = M4N[M4N[m]]
|
||
|
p = None
|
||
|
print(f" lookfor p {dxp=},{dyp=}")
|
||
|
for i in range(1,10):
|
||
|
cp = (xn-dxn+i*dxp,yn-dyn+i*dyp)
|
||
|
#print(f'{cp=}')
|
||
|
if cp in T[M4N[M4N[m]]]:
|
||
|
p = cp
|
||
|
print(" found p", p)
|
||
|
break
|
||
|
if p:
|
||
|
print((x,y),n,p)
|
||
|
M+=1
|
||
|
# break
|
||
|
print(M)
|
||
|
|
||
|
|