Files
OFFELLIA_Quantis/OFFELLIA_Pollard-Rho_Helicoidal.py
ModelHub XC 86836ec189 初始化项目,由ModelHub XC社区提供模型
Model: Brunobkr/OFFELLIA_Quantis
Source: Original Platform
2026-08-11 10:11:17 +08:00

325 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
OFFELLIA FATORADOR v2 — Decomposição Primo-Modal Helicoidal
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Teoria : Roda mod 42 — Crivo Becker-GPT
Autor : Bruno Becker | Zenodo DOI:10.5281/zenodo.18772809
Hierarquia de métodos:
1. Pilares de Origem {2, 3, 5, 7} — serial, O(1)
2. Pollard-Rho Helicoidal — O(n^1/4), sementes nos braços
"""
import time
import math
import multiprocessing
from concurrent.futures import ProcessPoolExecutor
from typing import Tuple, Dict
from datetime import datetime
from random import randint
# ══════════════════════════════════════════════════════════════════
# A MATRIZ SAGRADA — 12 BRAÇOS (MOD 42)
# ══════════════════════════════════════════════════════════════════
ARMS = [1, 5, 11, 13, 17, 19, 23, 25, 29, 31, 37, 41]
PILARES = [2, 3, 5, 7]
# ══════════════════════════════════════════════════════════════════
# POLLARD-RHO HELICOIDAL — Becker-GPT
#
# Sementes x₀ e c ancoradas nos 12 braços mod 42.
# Preserva O(n^1/4) + geometria helicoidal determinística.
# ══════════════════════════════════════════════════════════════════
def pollard_rho_helicoidal(n: int, tentativas: int = 5) -> Tuple[int, int]:
if n % 2 == 0: return 2, 1
for t in range(tentativas):
arm_x = ARMS[t % 12]
k_x = randint(1, max(1, int(n ** 0.25) // 42 + 10))
x = (42 * k_x + arm_x) % n or arm_x
arm_c = ARMS[(t + 5) % 12]
k_c = randint(0, 256)
c = (42 * k_c + arm_c) % n or arm_c
y, d, r, q, ys, x_save = x, 1, 1, 1, x, x
while d == 1:
x_save = y
for _ in range(r):
y = (y * y + c) % n
k = 0
while k < r and d == 1:
ys = y
for _ in range(min(128, r - k)):
y = (y * y + c) % n
q = (q * abs(x_save - y)) % n
k += 128
d = math.gcd(q, n)
r *= 2
if r > 2: break
if d == n:
d = 1
while d == 1:
ys = (ys * ys + c) % n
d = math.gcd(abs(x_save - ys), n)
if 1 < d < n: return d, t + 1
return -1, tentativas
def pollard_rho_worker(args: Tuple[int, int, int]) -> int:
"""Worker paralelo com braços-semente distintos."""
n, seed_offset, tentativas = args
for t in range(tentativas):
arm_idx = (t + seed_offset) % 12
x = (42 * randint(1, max(1, int(n ** 0.25) // 42 + 10)) + ARMS[arm_idx]) % n or ARMS[arm_idx]
c = (42 * randint(0, 256) + ARMS[(arm_idx + 5) % 12]) % n or ARMS[(arm_idx + 5) % 12]
y, d, r, q, ys, x_save = x, 1, 1, 1, x, x
while d == 1:
x_save = y
for _ in range(r):
y = (y * y + c) % n
k = 0
while k < r and d == 1:
ys = y
for _ in range(min(128, r - k)):
y = (y * y + c) % n
q = (q * abs(x_save - y)) % n
k += 128
d = math.gcd(q, n)
r *= 2
if r > 9_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999_999: break
if d == n:
d = 1
while d == 1:
ys = (ys * ys + c) % n
d = math.gcd(abs(x_save - ys), n)
if 1 < d < n: return d
return -1
# ══════════════════════════════════════════════════════════════════
# FATORAÇÃO PRINCIPAL — APENAS POLLARD-RHO HELICOIDAL
# ══════════════════════════════════════════════════════════════════
def fatorar_v2(n: int, num_cores: int) -> Dict:
original, fatores, passos = n, [], []
total_div = workers_usados = 0
metodos_usados = set()
t_inicio = time.perf_counter()
# ── Fase 1: Pilares ──
for pilar in PILARES:
while n % pilar == 0:
fatores.append(pilar)
passos.append({"etapa": "Pilar de Origem", "metodo": "Pilares",
"divisor": pilar, "quociente": n // pilar, "paralelo": False})
n //= pilar
total_div += 1
metodos_usados.add("Pilares")
# ── Fase 2: SOMENTE Pollard-Rho Helicoidal (sem linear) ──
while n > 1:
fator = -1
metodo = ""
paralelo = False
# Pollard-Rho Helicoidal (sempre executado)
metodos_usados.add("Pollard-Rho Helicoidal")
if num_cores > 1:
n_workers = min(num_cores, 12)
workers_usados = max(workers_usados, n_workers)
try:
with ProcessPoolExecutor(max_workers=n_workers) as ex:
for res in ex.map(pollard_rho_worker, [(n, i*2, 15) for i in range(n_workers)]):
if res != -1:
fator = res
paralelo = True
break
except Exception:
fator, _ = pollard_rho_helicoidal(n, 256)
else:
fator, _ = pollard_rho_helicoidal(n, 256)
metodo = "Pollard-Rho Helicoidal"
if fator == -1:
fatores.append(n)
passos.append({"etapa": "Primo Residual (Exaustivo)", "metodo": "Exaustivo",
"divisor": n, "quociente": 1, "paralelo": False})
n = 1
break
fatores.append(fator)
passos.append({"etapa": f"Braço mod 42 (d ≡ {fator % 42} mod 42)", "metodo": metodo,
"divisor": fator, "quociente": n // fator, "paralelo": paralelo})
n //= fator
total_div += 1
t_fim = time.perf_counter()
fatores_exp = {}
for f in fatores:
fatores_exp[f] = fatores_exp.get(f, 0) + 1
return {
"original": original, "fatores": sorted(fatores),
"fatores_exp": dict(sorted(fatores_exp.items())), "passos": passos,
"total_divisoes": total_div, "tempo_segundos": t_fim - t_inicio,
"num_cores": num_cores, "workers_usados": workers_usados,
"metodos_usados": sorted(metodos_usados),
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
}
# ══════════════════════════════════════════════════════════════════
# RELATÓRIO TXT (formato 100% idêntico ao original)
# ══════════════════════════════════════════════════════════════════
def gerar_relatorio(resultado: Dict, filename: str):
n = resultado["original"]
fatores = resultado["fatores"]
fat_exp = resultado["fatores_exp"]
passos = resultado["passos"]
tempo = resultado["tempo_segundos"]
cores = resultado["num_cores"]
workers = resultado["workers_usados"]
ts = resultado["timestamp"]
metodos = resultado["metodos_usados"]
notacao = " × ".join(f"{p}^{e}" if e > 1 else str(p) for p, e in fat_exp.items())
produto = 1
for f in fatores: produto *= f
verificacao = "CORRETO" if produto == n else f"ERRO (produto={produto})"
sep = "=" * 76
sep2 = "-" * 76
L = []
L.append(sep)
L.append(" OFFELLIA FATORADOR v2 — Decomposição Primo-Modal Helicoidal")
L.append(" Teoria : Roda mod 42 (Crivo Becker-GPT)")
L.append(" Métodos: Pollard-Rho Helicoidal")
L.append(" Autor : Bruno Becker | Zenodo DOI:10.5281/zenodo.18772809")
L.append(sep)
L.append(f" Data/Hora : {ts}")
L.append(f" Núcleos disponíveis : {cores}")
L.append(f" Workers paralelos : {workers if workers > 0 else 'Não utilizados (serial)'}")
L.append(f" Métodos utilizados : {' | '.join(metodos)}")
L.append(sep)
L.append("")
L.append("[ NÚMERO ANALISADO ]")
L.append(f" N : {n:,}")
L.append(f" Dígitos : {len(str(n))}")
L.append(f" Bits : {n.bit_length()}")
L.append(f" É primo? : {'Sim' if len(fat_exp)==1 and list(fat_exp.values())[0]==1 else 'Não'}")
L.append("")
L.append("[ RESULTADO DA FATORAÇÃO ]")
L.append(f" Notação de potência : {notacao}")
L.append(f" Fatores (lista) : {fatores}")
L.append(f" Fatores únicos : {sorted(fat_exp.keys())}")
L.append(f" Verificação : {n:,} = {notacao}{verificacao}")
L.append("")
L.append("[ MÉTRICAS DE EXECUÇÃO ]")
L.append(f" Tempo total : {tempo:.6f} segundos")
L.append(f" Divisões realizadas : {resultado['total_divisoes']}")
L.append(f" Fatores encontrados : {len(fatores)}")
L.append(f" Fatores distintos : {len(fat_exp)}")
if tempo > 0:
L.append(f" Fatores/segundo : {len(fatores)/tempo:.2f}")
L.append("")
L.append("[ DETALHAMENTO DOS FATORES ]")
L.append(f" {'Fator':>22} {'Exp':>4} {'Bits':>6} {'Origem'}")
L.append(" " + sep2)
for p, e in fat_exp.items():
origem = "Pilar de Origem" if p in PILARES else f"Braço {p % 42} (mod 42)"
L.append(f" {p:>22,} {e:>4} {p.bit_length():>6} {origem}")
L.append("")
L.append("[ PASSO A PASSO DA DECOMPOSIÇÃO ]")
L.append(f" {'#':<5} {'Método':<24} {'Etapa':<256} {'Divisor':>16} {'Quociente':>20} {'Par':>4}")
L.append(" " + sep2)
for i, p in enumerate(passos, 1):
L.append(f" {i:<5} {p['metodo']:<24} {p['etapa']:<256} "
f"{p['divisor']:>16,} {p['quociente']:>20,} {'S' if p['paralelo'] else 'N':>4}")
L.append("")
L.append("[ TEORIA APLICADA — HIERARQUIA DE MÉTODOS ]")
L.append("")
L.append(" 1. PILARES DE ORIGEM {2, 3, 5, 7} — O(1), serial")
L.append(" 2. MILLER-RABIN — O(k·log²n), determinístico até 3.3×10²⁴")
L.append(" 3. POLLARD-RHO HELICOIDAL (inovação Becker-GPT)")
L.append(" x₀ = 42k + a (a ∈ ARMS) — semente no braço")
L.append(" c = 42k + a (a ∈ ARMS) — parâmetro helicoidal")
L.append(" Complexidade: O(n^1/4)")
L.append(" 3. BUSCA LINEAR NOS BRAÇOS — fallback garantido, 28.6% candidatos")
L.append("")
L.append(" Todo primo p > 7: p ≡ a (mod 42),")
L.append(" a ∈ {1, 5, 11, 13, 17, 19, 23, 25, 29, 31, 37, 41}")
bracos = sorted(set(p["divisor"] % 42 for p in passos if p["divisor"] not in PILARES))
if bracos:
L.append(f" Braços utilizados : {bracos}")
L.append("")
L.append(sep)
L.append(" Fim do Relatório — OFFELLIA Fatorador v2")
L.append(" Zenodo: https://zenodo.org/records/18772809")
L.append(sep)
with open(filename, "w", encoding="utf-8") as f:
f.write("\n".join(L))
f.write("\n")
# ══════════════════════════════════════════════════════════════════
# INTERFACE PRINCIPAL (100% igual)
# ══════════════════════════════════════════════════════════════════
def run_fatorador():
print("=" * 64)
print(" OFFELLIA FATORADOR v2 — Pollard-Rho Helicoidal")
print(" Roda mod 42 | Pollard-Rho Helicoidal")
print("=" * 64)
try:
n = int(input("\nInsira o número a fatorar: "))
if n < 2:
print("Número deve ser >= 2.")
return
except ValueError:
print("Entrada inválida.")
return
num_cores = min(12, multiprocessing.cpu_count())
print(f"\nNúcleos ativos : {num_cores}")
print(f"Número analisado : {n:,} ({len(str(n))} dígitos | {n.bit_length()} bits)")
print("\nIniciando decomposição...\n")
resultado = fatorar_v2(n, num_cores)
fat_exp = resultado["fatores_exp"]
notacao = " × ".join(f"{p}^{e}" if e > 1 else str(p) for p, e in fat_exp.items())
tempo = resultado["tempo_segundos"]
print("" * 64)
print(f" ✓ Fatoração concluída em {tempo:.6f} segundos")
print(f" {n:,} = {notacao}")
print(f" Divisões realizadas : {resultado['total_divisoes']}")
print(f" Fatores distintos : {len(fat_exp)}")
print(f" Métodos usados : {' | '.join(resultado['metodos_usados'])}")
print("" * 64)
filename = f"offellia_v2_{n}.txt"
gerar_relatorio(resultado, filename)
print(f"\n Relatório salvo: '{filename}'")
print(" Operação finalizada.\n")
if __name__ == "__main__":
run_fatorador()