import numpy as np, itertools from collections import defaultdict from pin import fiber cp=(0,1,1,1,1,1); p=len(cp); Z=7 rng=np.random.default_rng(89) table=defaultdict(set) for _ in range(1500): c=fiber(cp,60,Z+3) for k in range(1,Z+1): for t in range(5,55): a=lambda kk,tt: c[kk][tt] Dk=a(k,t)^a(k,t+p); Dk1=a(k-1,t)^a(k-1,t+p) corr=(a(k,t)|a(k-1,t))^(a(k,t+p)|a(k-1,t+p)) table[(k,t%p,Dk1,Dk)].add(corr) def corr_options(k,ph,Dk1,Dk): s=table.get((k,ph,Dk1,Dk)) return s if s else {0,1} # unseen situation: allow both (conservative) def nexts(ph,D,x): # D = (D1..DZ), x = input D_{Z+1} full=(0,)+D+(x,) # D0=0 (same lighthouse), D_{Z+1}=x opts=[[full[k+1]^c for c in corr_options(k,ph,full[k-1],full[k])] for k in range(1,Z+1)] return [((ph+1)%p,tuple(o)) for o in itertools.product(*opts)] states=[(ph,D) for ph in range(p) for D in itertools.product((0,1),repeat=Z)] def ok(ph,D): return not (cp[ph]==1 and D[0]==1) # watchman: no difference at lantern 1 on lit nights safe={s for s in states if ok(*s)} while True: new={s for s in safe if any(all(n in safe for n in nexts(*s,x)) for x in (0,1))} if new==safe: break safe=new forced=both=0 for s in safe: good=[x for x in (0,1) if all(n in safe for n in nexts(*s,x))] if len(good)==1: forced+=1 elif len(good)==2: both+=1 print(f"pinned-zone machine for 011111 (lanterns 1-{Z}): {len(states)} states, {len(safe)} safe") print(f" in safe states, the incoming difference is FORCED in {forced}, free in {both}") nz=[s for s in safe if any(s[1])] print(f" safe states with any difference inside the zone: {len(nz)}") print(" safe states (phase, differences at lanterns 1-7) -> allowed incoming difference -> next state:") for s in sorted(safe): good=[x for x in (0,1) if all(n in safe for n in nexts(*s,x))] nx={x:sorted(set(nexts(*s,x))) for x in good} print(f" phase {s[0]} D={''.join(map(str,s[1]))} input {good} ->", {x:[(n[0],''.join(map(str,n[1]))) for n in v] for x,v in nx.items()})