#!/usr/bin/env python3 """Memory-efficient YB modulo space search. Generates combos on-the-fly instead of precomputing all.""" import sys, math, itertools sys.path.insert(0, '.') from multi_strand_braid import pairwise_coprime, cross, moduli_from_pairs, F_multi A0, S = [1, 2, 5, 6], 7 # Precompute coprime pairs up to 2000 pairs = [(p,q) for p in range(2, 2000) for q in range(p+1, 2000) if math.gcd(p,q) == 1] print(f"Coprime pairs: {len(pairs)}") def test_yb_4tuple(a, b, c, d): init = [(a,b),(c,d)] s1 = cross(init, 0, True) if not s1: return None s1s2 = cross(s1, 1, False) if not s1s2: return None s1s2s1 = cross(s1s2, 0, True) if not s1s2s1: return None s2 = cross(init, 1, False) if not s2: return None s2s1 = cross(s2, 0, True) if not s2s1: return None s2s1s2 = cross(s2s1, 1, False) if not s2s1s2: return None f1 = [F_multi(x, S, moduli_from_pairs(s1s2s1)) for x in A0] f2 = [F_multi(x, S, moduli_from_pairs(s2s1s2)) for x in A0] if f1 == f2: return (a,b,c,d,a*b*c*d,f1) return None # Smart search: iterate pairs but only check promising ones found = [] checked = 0 for i, (a,b) in enumerate(pairs): # For this pair, we need partner moduli beyond a+6 (3 over crossings) min_c = a + 7 # strand2 min must exceed strand1 max after crossings for j in range(i+1, len(pairs)): c, d = pairs[j] if c < min_c: continue if not pairwise_coprime([a,b,c,d]): continue checked += 1 if checked > 100000: break result = test_yb_4tuple(a, b, c, d) if result: found.append(result) a,b,c,d,M,f1 = result print(f"YB #{len(found)}: [{a},{b}]x[{c},{d}] M={M}") if checked > 100000: break print(f"\nChecked: {checked}") print(f"YB-valid: {len(found)}") if found: smallest = min(found, key=lambda x: x[4]) print(f"\nSmallest YB configuration:") print(f" Strand1: ({smallest[0]},{smallest[1]})") print(f" Strand2: ({smallest[2]},{smallest[3]})") print(f" M = {smallest[4]}") print(f" FA = {smallest[5]}")