aoc2024/d06/part2.py

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)