**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
80 lines
2.0 KiB
Python
80 lines
2.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
collatz_generate_base_validation.py
|
|
|
|
Generate base validation report (trajectories 1 to N*). Outputs Markdown; for PDF use pandoc.
|
|
|
|
Usage: python collatz_generate_base_validation.py --Nstar N --output PATH
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
from collatz_k_core import U_step
|
|
|
|
|
|
def collatz_steps(n: int) -> int:
|
|
"""Number of steps to reach 1 (accelerated on odds)."""
|
|
steps = 0
|
|
x = n
|
|
while x > 1:
|
|
if x % 2 == 0:
|
|
x //= 2
|
|
else:
|
|
x, _ = U_step(x)
|
|
steps += 1
|
|
return steps
|
|
|
|
|
|
def main() -> None:
|
|
ap = argparse.ArgumentParser(description="Generate base validation (1 to N*)")
|
|
ap.add_argument("--Nstar", type=int, required=True, help="Upper bound N*")
|
|
ap.add_argument("--output", required=True, help="Output path (.md or .pdf)")
|
|
args = ap.parse_args()
|
|
|
|
lines = [
|
|
"# Validation de base",
|
|
"",
|
|
"## Introduction",
|
|
"",
|
|
f"Vérification des trajectoires pour n = 1 à {args.Nstar}.",
|
|
"",
|
|
"## Résultats",
|
|
"",
|
|
]
|
|
|
|
ok_count = 0
|
|
for n in range(1, args.Nstar + 1):
|
|
try:
|
|
collatz_steps(n)
|
|
ok_count += 1
|
|
except Exception:
|
|
pass
|
|
|
|
lines.extend([
|
|
f"- Entiers vérifiés : {ok_count} / {args.Nstar}",
|
|
"",
|
|
])
|
|
|
|
out_path = Path(args.output)
|
|
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
md_content = "\n".join(lines)
|
|
|
|
if out_path.suffix.lower() == ".pdf":
|
|
out_md = out_path.with_suffix(".md")
|
|
out_md.write_text(md_content, encoding="utf-8")
|
|
try:
|
|
import subprocess
|
|
subprocess.run(["pandoc", str(out_md), "-o", str(out_path)], check=True)
|
|
except (FileNotFoundError, subprocess.CalledProcessError):
|
|
out_path.write_text(md_content, encoding="utf-8")
|
|
else:
|
|
out_path.write_text(md_content, encoding="utf-8")
|
|
|
|
print(f"Wrote {out_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|