**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
64 lines
1.7 KiB
Python
64 lines
1.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
collatz_verify_Nstar_range.py
|
|
|
|
For n=1 to N, run Collatz trajectory until 1. Use U_step from collatz_k_core
|
|
for accelerated trajectory on odds. Output CSV: n, steps, ok.
|
|
|
|
Usage:
|
|
python collatz_verify_Nstar_range.py --Nstar N --output CSV_PATH
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
import argparse
|
|
import csv
|
|
from pathlib import Path
|
|
|
|
from collatz_k_core import U_step
|
|
|
|
|
|
def collatz_steps_to_one(n: int) -> tuple[int, bool]:
|
|
"""
|
|
Run Collatz trajectory from n until 1.
|
|
Returns (steps, ok) where ok=True if trajectory reached 1.
|
|
Uses U_step for accelerated trajectory on odd numbers.
|
|
"""
|
|
steps = 0
|
|
while n != 1:
|
|
if n <= 0:
|
|
return steps, False
|
|
if n % 2 == 1:
|
|
n, a = U_step(n)
|
|
steps += 1 + a # one 3n+1, then a divisions by 2
|
|
else:
|
|
n = n // 2
|
|
steps += 1
|
|
return steps, True
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
description="Verify Collatz conjecture for n=1..N, output CSV"
|
|
)
|
|
parser.add_argument("--Nstar", type=int, required=True, help="Upper bound N (inclusive)")
|
|
parser.add_argument("--output", required=True, help="Output CSV path")
|
|
args = parser.parse_args()
|
|
|
|
nstar = args.Nstar
|
|
if nstar < 1:
|
|
raise SystemExit("Nstar must be >= 1")
|
|
|
|
out_path = Path(args.output)
|
|
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
with out_path.open("w", newline="", encoding="utf-8") as f:
|
|
w = csv.writer(f)
|
|
w.writerow(["n", "steps", "ok"])
|
|
for n in range(1, nstar + 1):
|
|
steps, ok = collatz_steps_to_one(n)
|
|
w.writerow([n, steps, ok])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|