diff --git a/day06.py b/day06.py new file mode 100644 index 0000000..5b0f82a --- /dev/null +++ b/day06.py @@ -0,0 +1,81 @@ +#!/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