From 611e99dbf5da42b55e467ef4ce3a64bb76de4430 Mon Sep 17 00:00:00 2001 From: setop Date: Fri, 23 Dec 2022 21:04:46 +0100 Subject: [PATCH] day 23, game set and match --- d23/run.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 d23/run.py diff --git a/d23/run.py b/d23/run.py new file mode 100644 index 0000000..044b615 --- /dev/null +++ b/d23/run.py @@ -0,0 +1,65 @@ +import sys + +E = { (y,x) for y,l in enumerate(sys.stdin.read().splitlines()) + for x,c in enumerate(l) + if c == '#' } + +def can(y,x): + can1 = (y-1,x-1) not in E + can2 = (y-1,x) not in E + can3 = (y-1,x+1) not in E + can4 = (y,x+1) not in E + can5 = (y+1,x+1) not in E + can6 = (y+1,x) not in E + can7 = (y+1,x-1) not in E + can8 = (y,x-1) not in E + return [can1,can2,can3,can4,can5,can6,can7,can8] + +def canN(y,x,can1,can2,can3,can4,can5,can6,can7,can8): + if can1 and can2 and can3: + return (y-1,x) +def canS(y,x,can1,can2,can3,can4,can5,can6,can7,can8): + if can5 and can6 and can7: + return (y+1,x) +def canW(y,x,can1,can2,can3,can4,can5,can6,can7,can8): + if can7 and can8 and can1: + return (y,x-1) +def canE(y,x,can1,can2,can3,can4,can5,can6,can7,can8): + if can3 and can4 and can5: + return (y,x+1) + +def dim(): + minx = min(x for (_,x) in E) + maxx = max(x for (_,x) in E) + miny = min(y for (y,_) in E) + maxy = max(y for (y,_) in E) + return (maxx-minx+1,maxy-miny+1) # W,H + +from collections import deque +dirs = deque([canN,canS,canW,canE]) +for r in range(int(sys.argv[1])): # rounds + P = dict() # { new_pos: old_pos } + for e in E: # for each elve + (y,x) = e + cans = can(y,x) # compute once instead of four + moves = [ d(y,x,*cans) for d in dirs ] + if all(m is not None for m in moves): # far away + continue + if all(m is None for m in moves): # all packed + continue + p = next(filter(lambda m: m is not None ,moves)) + if p not in P: # can move + P[p] = (y,x) + else: # occupied, invalidate move for all + P[p] = None + moved = { v for k,v in P.items() if v is not None } + newpos = { k for k,v in P.items() if v is not None } + if r+1 == 10: + (W,H) = dim() + print(W, H, W * H - len(E)) + if len(newpos) == 0: + (W,H) = dim() + print(f"no move after {r+1}, {W}, {H}") + break + E = (E - moved) | newpos + dirs.rotate(-1)