#!/usr/bin/env python3 """T31 · сводка двух проходов судьи: флаг засчитан, если оба прохода hit; расхождение — в runs/disagree.json на ручную проверку. Принято = нет блокеров B1–B5 (B4 — скрипт ИЛИ судья) и ответ получен (нет ответа = не принято, знаменатель 12).""" import json, collections from pathlib import Path HERE = Path(__file__).resolve().parent J = {} for n in (1, 2): for line in (HERE / "runs" / f"judge-{n}.jsonl").read_text(encoding="utf-8").splitlines(): r = json.loads(line) J.setdefault((r["short"], r["item"], r["layer"]), {})[n] = r.get("flags") or {} S = {(x["short"], x["item"], x["layer"]): x for x in json.loads((HERE / "runs" / "parsed.json").read_text(encoding="utf-8"))} B = ("B1", "B2", "B3", "B4", "B5") hit = lambda f, k: bool((f.get(k) or {}).get("hit")) if isinstance(f.get(k), dict) else False dis, rows = [], collections.defaultdict(lambda: collections.Counter()) for key, p in J.items(): s, i, L = key c = rows[(L, s)]; c["n"] += 1 ok = True for k in B + ("M3", "META"): a, b = hit(p.get(1, {}), k), hit(p.get(2, {}), k) if a != b: dis.append(dict(key=list(key), flag=k, q1=(p[1].get(k) or {}).get("quote"), q2=(p[2].get(k) or {}).get("quote"))) v = a and b if k == "B4": v = v or S[key]["b4"] if v: c[k] += 1 if k in B: ok = False c["accepted"] += ok (HERE / "runs" / "disagree.json").write_text(json.dumps(dis, ensure_ascii=False, indent=1), encoding="utf-8") out = {f"{L}/{s}": dict(c) for (L, s), c in sorted(rows.items())} (HERE / "runs" / "summary-auto.json").write_text(json.dumps(out, ensure_ascii=False, indent=1), encoding="utf-8") for k, c in out.items(): print(k, "получено", c["n"], "/12 принято", c.get("accepted", 0), " ".join(f"{f}={c.get(f, 0)}" for f in B + ("M3", "META"))) print("расхождений проходов", len(dis), collections.Counter(d["flag"] for d in dis))