**Motivations:** - Implémenter le workflow complet de démonstration Collatz (commandes.md) - Permettre la reprise après interruption au palier D20 **Evolutions:** - Scripts 01-12 et run-full-workflow alignés sur commandes.md sections 1-10 - collatz_recover_noyau.py : recréation de noyau_post_D20 à partir du CSV candidats - Option --resume-from D20 dans collatz_k_pipeline pour reprendre sans recalculer D18-D19-F15 - Détection automatique : si candidats_D20 existe sans noyau_post_D20, récupération puis poursuite - Filtres --cible=critique et --modulo dans collatz_fusion_pipeline - ROOT par défaut = collatz_k_scripts (plus data/source vide) **Pages affectées:** - .gitignore (__pycache__, out/) - applications/collatz/collatz_k_scripts/*.py - applications/collatz/scripts/*.sh - applications/collatz/scripts/README.md
69 lines
2.2 KiB
Python
69 lines
2.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
collatz_calculate_Nstar.py
|
|
|
|
Scan certificats/*.json for N0 values in clauses, compute N* = max of all N0,
|
|
write markdown with "N* = <value>".
|
|
|
|
Usage:
|
|
python collatz_calculate_Nstar.py --certificats-dir DIR --output MD_PATH
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
def scan_n0_values(certificats_dir: Path) -> list[int]:
|
|
"""Scan certificat_*.json and candidats_*.csv for N0 values."""
|
|
import csv
|
|
|
|
n0_values: list[int] = []
|
|
for p in sorted(certificats_dir.glob("certificat_*.json")):
|
|
data = json.loads(p.read_text(encoding="utf-8"))
|
|
clauses = data.get("clauses", data.get("closed", []))
|
|
for c in clauses:
|
|
if isinstance(c, dict) and "N0" in c:
|
|
n0_values.append(int(c["N0"]))
|
|
|
|
parent = certificats_dir.resolve().parent
|
|
for search_dir in (parent, parent / "candidats"):
|
|
if not search_dir.is_dir():
|
|
continue
|
|
for p in sorted(search_dir.glob("candidats_*.csv")):
|
|
with p.open("r", encoding="utf-8") as f:
|
|
reader = csv.DictReader(f)
|
|
for row in reader:
|
|
n0_col = next((k for k in row if "N0" in k or k == "N0"), None)
|
|
if n0_col and row.get(n0_col):
|
|
try:
|
|
n0_values.append(int(row[n0_col]))
|
|
except ValueError:
|
|
pass
|
|
return n0_values
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
description="Compute N* = max of all N0 from certificat JSON files"
|
|
)
|
|
parser.add_argument("--certificats-dir", required=True, help="Directory containing certificat_*.json")
|
|
parser.add_argument("--output", required=True, help="Output markdown path")
|
|
args = parser.parse_args()
|
|
|
|
cert_dir = Path(args.certificats_dir)
|
|
if not cert_dir.is_dir():
|
|
raise SystemExit(f"Not a directory: {cert_dir}")
|
|
|
|
n0_values = scan_n0_values(cert_dir)
|
|
nstar = max(n0_values) if n0_values else 0
|
|
|
|
out_path = Path(args.output)
|
|
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
out_path.write_text(f"N* = {nstar}\n", encoding="utf-8")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|