#!/usr/bin/env python3 m = [] obstacles = set() start = (-1,-1) lx = ly = 0 with open('day06') as f: for y,l in enumerate(f): ly += 1 lx = lx or len(l) for x,ll in enumerate(l): match ll: case '#': obstacles.add((y,x)) case '^': start = (y,x) lookup = { (-1, 0): ( 0, 1), ( 0, 1): ( 1, 0), ( 1, 0): ( 0,-1), ( 0,-1): (-1, 0) } # 1 def walk(pos, dir): visited = [] visited.append((pos, dir)) npos = (pos[0]+dir[0], pos[1]+dir[1]) while True: while npos not in obstacles: pos = npos visited.append((pos,dir)) npos = (pos[0]+dir[0], pos[1]+dir[1]) if npos[0]==ly or npos[0]==-1: return visited if npos[1]==lx or npos[1]==-1: return visited dir = lookup[dir] npos = (pos[0]+dir[0], pos[1]+dir[1]) visited = walk(start, (-1,0)) vpos = set([v[0] for v in visited]) res1 = len(vpos) # 2 def loop(pos, dir, sv, obstacles): while True: npos = (pos[0] + dir[0], pos[1] + dir[1]) if npos[0]==ly or npos[0]==-1: return False if npos[1]==lx or npos[1]==-1: return False while npos not in obstacles: sv.add((pos,dir)) pos = npos npos = (pos[0]+dir[0], pos[1]+dir[1]) if (pos, dir) in sv: return True if npos[0]==ly or npos[0]==-1: return False if npos[1]==lx or npos[1]==-1: return False dir = lookup[dir] done = set() res2 = 0 for k,(pos,_) in enumerate(visited): if pos == start: continue if pos in obstacles: continue if pos in done: continue done.add(pos) start = visited[k-1][0] dir = visited[k-1][1] sv = set(visited[:k]) if loop(start, dir, sv, obstacles | {pos}): res2 += 1