day 23, animate elves' spreading
This commit is contained in:
parent
611e99dbf5
commit
ccb284ef87
|
@ -0,0 +1,69 @@
|
|||
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 draw(r):
|
||||
with open(f"./pics/{r:05d}.pbm","wt") as f:
|
||||
(minx,maxx,miny,maxy) = (-13,129,-13,129)
|
||||
w = 4*(maxx -minx +1)
|
||||
print("P1",file=f)
|
||||
print(f"{w} {w}", file=f)
|
||||
for y in range(miny,maxy+1):
|
||||
a="".join(["0000","1111"][(y,x) in E] for x in range(minx,maxx+1))
|
||||
print(a,file=f)
|
||||
print(a,file=f)
|
||||
print(a,file=f)
|
||||
print(a,file=f)
|
||||
|
||||
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 len(newpos) == 0:
|
||||
break
|
||||
if r % 11 == 0:
|
||||
draw(r)
|
||||
E = (E - moved) | newpos
|
||||
dirs.rotate(-1)
|
||||
# then, $TIME convert -delay 25 -loop 0 pics/* a.gif
|
Loading…
Reference in New Issue