{}
run-icon
main.js
// ============================================================ // CONFIGURACIÓN // ============================================================ const EXTENDED_MODE = true; // true: Múltiplos + Combinaciones (sumas/restas) const MAX_N = 999_999_999n; // Precisión interna (30 decimales) const PI_STR = "3141592653589793238462643383279"; const PI_VAL = BigInt(PI_STR); const PI_FACTOR = 10n ** 30n; const OUTPUT_SCALE = 10n ** 16n; // ============================================================ // LÓGICA MATEMÁTICA // ============================================================ function getSinEst(p, q) { let error = (p * PI_FACTOR) - (q * PI_VAL); // sin(p) ≈ (-1)^q * (p - q*pi) return (q % 2n === 0n) ? error : -error; } function getContinuedFraction(termsCount) { let terms = []; let p = PI_VAL, q = PI_FACTOR; for (let i = 0; i < termsCount; i++) { let a = p / q; terms.push(a); let next_q = p % q; p = q; q = next_q; if (q === 0n) break; } return terms; } function buildCandidates(limitN) { let cf = getContinuedFraction(50); let rawData = new Map(); // 1. CONVERGENTES let p_m2 = 0n, p_m1 = 1n, q_m2 = 1n, q_m1 = 0n; let convs = []; for (let a of cf) { let p = a * p_m1 + p_m2, q = a * q_m1 + q_m2; convs.push({ p, q, a }); if (p <= limitN) rawData.set(p, { q, source: "convergente" }); if (p > limitN) break; p_m2 = p_m1; p_m1 = p; q_m2 = q_m1; q_m1 = q; } // 2. SEMICONVERGENTES MATEMÁTICOS for (let i = 1; i < convs.length; i++) { let pk = convs[i - 1].p, qk = convs[i - 1].q, aNext = convs[i].a; let pPrev = (i === 1) ? 1n : convs[i - 2].p; let qPrev = (i === 1) ? 0n : convs[i - 2].q; for (let t = 1n; t < aNext; t++) { let p = t * pk + pPrev, q = t * qk + qPrev; if (p > limitN) break; if (!rawData.has(p)) rawData.set(p, { q, source: "semiconvergente" }); } } // 3. MODO EXTENDIDO (Múltiplos + Combinaciones) if (EXTENDED_MODE) { let baseItems = Array.from(rawData.entries()); // [p, {q, source}] // A. Múltiplos (del 2 al 10) baseItems.forEach(([p, data]) => { for (let k = 2n; k <= 10n; k++) { let np = p * k, nq = data.q * k; if (np <= limitN && !rawData.has(np)) { rawData.set(np, { q: nq, source: "múltiplo" }); } } }); // B. Combinaciones (Sumas y Restas) de los mejores // Seleccionamos los 10 candidatos con el error más bajo para combinar let sortedByError = Array.from(rawData.entries()) .map(([p, d]) => ({ p, q: d.q, err: getSinEst(p, d.q) })) .sort((a, b) => { let absA = a.err < 0n ? -a.err : a.err; let absB = b.err < 0n ? -b.err : b.err; return absA < absB ? -1 : 1; }) .slice(0, 10); for (let i = 0; i < sortedByError.length; i++) { for (let j = i + 1; j < sortedByError.length; j++) { let c1 = sortedByError[i]; let c2 = sortedByError[j]; // Probar Suma let sp = c1.p + c2.p; let sq = c1.q + c2.q; if (sp <= limitN && !rawData.has(sp)) { rawData.set(sp, { q: sq, source: "combinación" }); } // Probar Resta (valor absoluto) let rp = c1.p > c2.p ? c1.p - c2.p : c2.p - c1.p; let rq = c1.q > c2.q ? c1.q - c2.q : c2.q - c1.q; if (rp > 1n && !rawData.has(rp)) { rawData.set(rp, { q: rq, source: "combinación" }); } } } } return Array.from(rawData.entries()).map(([p, d]) => ({ n: p, q: d.q, sinEst: getSinEst(p, d.q), source: d.source })).sort((a, b) => a.n < b.n ? -1 : 1); } // ============================================================ // EJECUCIÓN // ============================================================ function run() { const MODE_TEXT = EXTENDED_MODE ? "EXTENDIDO (Total)" : "PURO"; console.log(`\n--- MODO ${MODE_TEXT} ---`); let candidates = buildCandidates(MAX_N); let validPairs = []; let pos = candidates.filter(c => c.sinEst > 0n); let neg = candidates.filter(c => c.sinEst < 0n); [pos, neg].forEach(group => { for (let i = 0; i < group.length; i++) { for (let j = i + 1; j < group.length; j++) { let c1 = group[i], c2 = group[j]; let prod = (c1.sinEst * c2.sinEst * OUTPUT_SCALE) / (PI_FACTOR * PI_FACTOR); if (prod === 0n) { let valNum = Number(c1.sinEst * c2.sinEst) * 1e16 / 1e60; validPairs.push({ x1: c1.n.toString(), x2: c2.n.toString(), "1e16*sin*sin": valNum.toExponential(10), floor: 0, tipo: `${c1.source}, ${c2.source}` }); } } } }); console.log(`Candidatos analizados: ${candidates.length}`); console.log(`Pares válidos encontrados: ${validPairs.length}`); if (validPairs.length > 0) { console.table(validPairs.sort((a,b) => Number(a.x1) - Number(b.x1))); } } run();
Output