XTaylorSpenceX

Phoenix Prime Calculator v1.0GX

Sep 18th, 2025
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 22.90 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width,initial-scale=1" />
  6. <title>Prime Decider</title>
  7. <style>
  8.   :root{
  9.     --bg:#071023;
  10.     --panel:#0f1720;
  11.     --muted:#9aa6b2;
  12.     --accent-a:#14b8a6; /* teal renegade */
  13.     --accent-b:#f97316; /* orange flame */
  14.     --accent-c:#ff8bd8; /* pink */
  15.     --glass: rgba(255,255,255,0.03);
  16.     --glass-2: rgba(255,255,255,0.02);
  17.     --hud: rgba(110,231,247,0.06);
  18.     --danger:#ff6b6b;
  19.     --success:#7ee787;
  20.     font-family: Inter, ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial;
  21.   }
  22.  
  23.   html,body{height:100%; background:linear-gradient(180deg,var(--bg), #02111a 80%); color:var(--muted); margin:0; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;}
  24.  
  25.   /* Layout */
  26.   .wrap{max-width:420px;margin:18px auto;padding:18px;display:block;}
  27.   header{display:flex;align-items:center;gap:14px;padding:10px 12px;border-radius:10px;background:linear-gradient(90deg,var(--panel),rgba(255,255,255,0.01));box-shadow:0 6px 20px rgba(2,6,12,0.6);border:1px solid rgba(255,255,255,0.03);}
  28.   h1{margin:0;font-size:1.15rem;color:var(--accent-a);letter-spacing:0.4px}
  29.   .sub{font-size:0.85rem;color:var(--muted);opacity:0.9}
  30.  
  31.   /* Panel */
  32.   .panel {background:linear-gradient(180deg,var(--panel),var(--glass));border-radius:10px;padding:14px;border:1px solid rgba(255,255,255,0.03);box-shadow:0 8px 30px rgba(2,6,12,0.6);}
  33.   .big-value{font-weight:700;font-size:3.05rem;color:var(--accent-b);text-align:center;margin:6px 0 2px 0;letter-spacing:1px;}
  34.   .small-sub{font-family:monospace;font-size:0.9rem;color:var(--muted);text-align:center;margin-bottom:8px}
  35.   .hud-row{display:flex;gap:10px;align-items:center;justify-content:center;margin:8px 0}
  36.   .stat{flex:1;background:var(--glass);padding:8px;border-radius:8px;border:1px solid rgba(255,255,255,0.02);text-align:center;}
  37.   .stat .label{font-size:0.78rem;color:var(--muted);margin-bottom:6px}
  38.   .stat .value{font-family:monospace;font-size:1.05rem;color:var(--accent-a);font-weight:600}
  39.  
  40.   /* Progress / waveform */
  41.   .progress-wrap{background:linear-gradient(90deg, rgba(255,255,255,0.01), rgba(255,255,255,0.01));padding:10px;border-radius:8px;margin-top:10px;border:1px solid rgba(255,255,255,0.02);}
  42.   #progress{width:100%;height:12px;background:linear-gradient(90deg,#072026,#0b2b36);border-radius:999px;overflow:hidden;border:1px solid rgba(0,0,0,0.6)}
  43.   #progress > i{display:block;height:100%;width:0%;background:linear-gradient(90deg,var(--accent-b),var(--accent-a));transition:width 160ms linear}
  44.  
  45.   canvas.hud-canvas{width:100%;height:56px;background:linear-gradient(180deg,rgba(255,255,255,0.01),transparent);border-radius:6px;display:block}
  46.  
  47.   #equation{font-family:monospace; font-size:0.8rem; color:var(--accent-c); text-align:center; margin-top:4px; padding:2px; background:var(--glass); border-radius:4px; border:1px solid rgba(255,255,255,0.02); height:3em; overflow:hidden; display:flex; align-items:center; justify-content:center;}
  48.  
  49.   /* Controls */
  50.   .controls{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin-top:12px}
  51.   .btn{background:transparent;border:1px solid rgba(255,255,255,0.04);padding:8px 12px;border-radius:8px;color:var(--muted);cursor:pointer;font-weight:600}
  52.   .btn.primary{background:linear-gradient(90deg,var(--accent-a),var(--accent-c));color:#02121c;border:none;box-shadow:0 6px 18px rgba(110,231,247,0.06)}
  53.   .btn.save{background:linear-gradient(90deg,#7ee787,#58a6ff);color:#02121c;border:none;box-shadow:0 6px 18px rgba(120,231,135,0.06)}
  54.   .btn.load{background:linear-gradient(90deg,#8957e5,#da3633);color:#fff;border:none;box-shadow:0 6px 18px rgba(137,87,229,0.06)}
  55.   .btn.ghost{background:transparent;border:1px dashed rgba(255,255,255,0.03)}
  56.  
  57.   /* Method list / controls */
  58.   .method-list{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
  59.   .method-pill{padding:6px 10px;border-radius:999px;border:1px solid rgba(255,255,255,0.03);background:linear-gradient(180deg,transparent,rgba(0,0,0,0.02));font-weight:600;font-size:0.85rem;color:var(--muted);cursor:pointer}
  60.   .method-pill.active{border-color:rgba(110,231,247,0.18);box-shadow:0 6px 18px rgba(17,61,68,0.12);color:var(--accent-a)}
  61.  
  62.   /* Tile for methods */
  63.   .tile{background:var(--glass-2);padding:12px;border-radius:10px;border:1px solid rgba(255,255,255,0.02);margin-top:12px}
  64.   .tile h3{margin:0;color:var(--accent-c);font-size:0.95rem}
  65.   .tile p{font-size:0.86rem;color:var(--muted);margin:8px 0 0 0}
  66.  
  67.   /* Terminal */
  68.   .terminal-wrap{margin-top:18px;}
  69.   .terminal-title{font-size:1rem;color:var(--accent-a);margin-bottom:8px;}
  70.   #terminal{height:200px;overflow:auto;background:var(--panel);padding:10px;border-radius:8px;border:1px solid var(--glass);font-family:monospace;font-size:0.8rem;color:var(--success);line-height:1.2;}
  71.  
  72.   footer{text-align:center;color:var(--muted);margin-top:12px;font-size:0.86rem}
  73.  
  74.   /* small inputs */
  75.   .row{display:flex;gap:8px;align-items:center}
  76.   input[type="text"], select{background:transparent;border:1px solid rgba(255,255,255,0.03);padding:8px;border-radius:8px;color:var(--muted);min-width:0}
  77.   input[type="file"]{display:none;}
  78.   label.small{font-size:0.78rem;color:var(--muted);margin-right:6px}
  79.  
  80.   /* responsive */
  81.   @media (max-width:980px){.wrap{padding:12px}}
  82. </style>
  83. </head>
  84. <body>
  85.   <div class="wrap">
  86.     <header>
  87.       <div style="display:flex;flex-direction:column">
  88.         <h1>Prime Decider</h1>
  89.         <div class="sub">Infinite prime counting • 7 methods • Loading bar with error checking</div>
  90.       </div>
  91.     </header>
  92.  
  93.     <!-- HUD panel -->
  94.     <section class="panel">
  95.       <div class="small-sub">CURRENT PRIME</div>
  96.       <div class="big-value" id="bigPrime">7</div>
  97.       <div class="small-sub" id="primeSub">calculated by Trial Division</div>
  98.  
  99.       <div class="hud-row">
  100.         <div class="stat">
  101.           <div class="label">Primes Found</div>
  102.           <div class="value" id="primesFound">4</div>
  103.         </div>
  104.         <div class="stat">
  105.           <div class="label">Current N</div>
  106.           <div class="value" id="currentN">21</div>
  107.         </div>
  108.         <div class="stat">
  109.           <div class="label">Runtime</div>
  110.           <div class="value" id="runtime">00:00:00</div>
  111.         </div>
  112.       </div>
  113.  
  114.       <div class="progress-wrap">
  115.         <div id="progress"><i id="progressBar"></i></div>
  116.         <canvas class="hud-canvas" id="wave" width="800" height="56"></canvas>
  117.         <div style="display:flex;justify-content:space-between;margin-top:8px">
  118.           <div style="font-family:monospace;color:var(--muted);font-size:0.85rem" id="calcMsg">Idle</div>
  119.           <div style="font-family:monospace;color:var(--muted);font-size:0.85rem" id="speedLabel">Speed: 1x</div>
  120.         </div>
  121.         <div id="equation"></div>
  122.       </div>
  123.  
  124.       <div class="controls">
  125.         <button class="btn primary" id="toggleBtn">Start</button>
  126.         <button class="btn" id="stepBtn" title="Advance one number">Step</button>
  127.         <button class="btn save" id="saveBtn" title="Save primes to .txt">Save</button>
  128.         <label for="loadFile" class="btn load" title="Load primes from .txt">Load</label>
  129.         <input type="file" id="loadFile" accept=".txt">
  130.       </div>
  131.  
  132.       <div style="margin-top:12px;display:flex;gap:8px;align-items:center;justify-content:center">
  133.         <label class="small">Speed</label>
  134.         <select id="speedSelect" style="min-width:88px">
  135.           <option value="1">1x</option>
  136.           <option value="2">2x</option>
  137.           <option value="5">5x</option>
  138.           <option value="10">10x</option>
  139.         </select>
  140.         <label class="small">Start N</label>
  141.         <input type="text" id="startN" value="21" />
  142.       </div>
  143.  
  144.       <div class="tile">
  145.         <h3>Method Pipeline</h3>
  146.         <p>Choose which prime tests rotate through. Click to enable/disable.</p>
  147.         <div class="method-list" id="methodList">
  148.           <!-- pills injected by JS -->
  149.         </div>
  150.       </div>
  151.     </section>
  152.  
  153.     <div class="terminal-wrap">
  154.       <div class="terminal-title">Output Terminal Window</div>
  155.       <div id="terminal"></div>
  156.     </div>
  157.  
  158.     <footer>Prime Decider • Infinite realm • Built for 20-40 years of runtime</footer>
  159.   </div>
  160.  
  161. <script>
  162. /* -----------------------------
  163.    BigInt utilities
  164. ------------------------------*/
  165. function modPow(base, exp, mod) {
  166.     let result = 1n;
  167.     base = base % mod;
  168.     while (exp > 0n) {
  169.         if (exp & 1n) {
  170.            result = (result * base) % mod;
  171.         }
  172.         base = (base * base) % mod;
  173.         exp = exp >> 1n;
  174.     }
  175.     return result;
  176. }
  177.  
  178. function bigSqrt(n) {
  179.     if (n === 0n || n === 1n) return n;
  180.     let low = 1n;
  181.     let high = n / 2n + 1n;
  182.     while (low < high) {
  183.        let mid = low + (high - low + 1n) / 2n;
  184.        if (mid * mid <= n) {
  185.            low = mid;
  186.        } else {
  187.            high = mid - 1n;
  188.        }
  189.    }
  190.    return low;
  191. }
  192.  
  193. /* -----------------------------
  194.   App state
  195. ------------------------------*/
  196. const state = {
  197.  currentN: 21n,
  198.  primes: [2n, 3n, 5n, 7n],
  199.  running: false,
  200.  progress: 0,
  201.  phase: 'calc',
  202.  speed: 1,
  203.  methodIndex: 0,
  204.  primaryMethod: null,
  205.  verifyMethod: null,
  206.  startTime: null,
  207.  methods: [
  208.    {id:'Trial Division', equation:'n % 2 ≠ 0 ∧ ∀ i=3 to √n step 2: n % i ≠ 0', fn:trialDivision, enabled:true},
  209.    {id:'Sieve Optimized', equation:'∀ p in known primes p≤√n: n % p ≠ 0', fn:sieveOptimized, enabled:true},
  210.    {id:'6k ± 1', equation:'n % 2=0 or %3=0? no; ∀ i=5 to √n step 6: n%i≠0 ∧ n%(i+2)≠0', fn:sixKOptimization, enabled:true},
  211.    {id:'Fermat Test', equation:'a^{n-1} ≡ 1 mod n for a=2,3,5', fn:fermatsTest, enabled:true},
  212.    {id:'Miller-Rabin', equation:'Strong pseudoprime to bases 2,3,5,7,11', fn:millerRabinTest, enabled:true},
  213.    {id:'Wheel Factorization', equation:'Check 30k + {1,7,11,13,17,19,23,29} up to √n', fn:wheelFactorization, enabled:true},
  214.    {id:'Solovay-Strassen', equation:'a^{(n-1)/2} ≡ (a/n) mod n for random a', fn:solovayStrassen, enabled:true}
  215.  ]
  216. };
  217.  
  218. /* -----------------------------
  219.   DOM refs
  220. ------------------------------*/
  221. const bigPrime = document.getElementById('bigPrime');
  222. const primeSub = document.getElementById('primeSub');
  223. const primesFound = document.getElementById('primesFound');
  224. const currentNEl = document.getElementById('currentN');
  225. const runtimeEl = document.getElementById('runtime');
  226. const progressBar = document.getElementById('progressBar');
  227. const calcMsg = document.getElementById('calcMsg');
  228. const equationEl = document.getElementById('equation');
  229. const speedLabel = document.getElementById('speedLabel');
  230. const toggleBtn = document.getElementById('toggleBtn');
  231. const stepBtn = document.getElementById('stepBtn');
  232. const saveBtn = document.getElementById('saveBtn');
  233. const loadFile = document.getElementById('loadFile');
  234. const methodList = document.getElementById('methodList');
  235. const terminal = document.getElementById('terminal');
  236.  
  237. document.getElementById('startN').addEventListener('change', e => {
  238.   const vStr = e.target.value.trim() || '2';
  239.   const v = BigInt(vStr);
  240.   state.currentN = v % 2n === 0n ? v + 1n : v;
  241.   updateUI();
  242. });
  243.  
  244. document.getElementById('speedSelect').addEventListener('change', e => {
  245.   state.speed = Number(e.target.value);
  246.   speedLabel.textContent = `Speed: ${state.speed}x`;
  247. });
  248.  
  249. function appendToTerminal(msg) {
  250.   const div = document.createElement('div');
  251.   div.textContent = msg;
  252.   terminal.appendChild(div);
  253.   terminal.scrollTop = terminal.scrollHeight;
  254. }
  255.  
  256. loadFile.addEventListener('change', e => {
  257.   const file = e.target.files[0];
  258.   if (!file) return;
  259.   const reader = new FileReader();
  260.   reader.onload = ev => {
  261.     try {
  262.       const content = ev.target.result;
  263.       const lines = content.split('\n').filter(line => line.trim());
  264.       const loadedPrimes = [];
  265.       lines.forEach(line => {
  266.         const parts = line.split('\t');
  267.         if (parts.length >= 2) {
  268.           const primeStr = parts[1].trim();
  269.           const prime = BigInt(primeStr);
  270.           loadedPrimes.push(prime);
  271.         }
  272.       });
  273.       if (loadedPrimes.length > 0) {
  274.         state.primes = [...new Set([...state.primes, ...loadedPrimes])].sort((a,b) => (a > b ? 1 : -1)); // unique sorted
  275.         state.currentN = state.primes.at(-1) + (state.primes.at(-1) % 2n === 0n ? 1n : 2n);
  276.         terminal.innerHTML = '';
  277.         state.primes.forEach(p => appendToTerminal(`PRIME: ${p.toString()}`));
  278.         state.progress = 0;
  279.         state.phase = 'calc';
  280.         state.methodIndex = 0;
  281.         state.startTime = new Date(); // reset runtime on load
  282.         updateUI();
  283.         appendToTerminal(`Loaded ${loadedPrimes.length} primes. Resuming from ${state.currentN.toString()}`);
  284.       } else {
  285.         appendToTerminal('No valid primes found in file.');
  286.       }
  287.     } catch (err) {
  288.       appendToTerminal('Load error: ' + err.message);
  289.     }
  290.   };
  291.   reader.readAsText(file);
  292.   e.target.value = '';
  293. });
  294.  
  295. saveBtn.onclick = () => {
  296.   let content = '';
  297.   state.primes.forEach((p, i) => {
  298.     content += `${i}\t${p.toString()}\n`;
  299.   });
  300.   const blob = new Blob([content], {type: 'text/plain'});
  301.   const url = URL.createObjectURL(blob);
  302.   const a = document.createElement('a');
  303.   a.href = url;
  304.   a.download = `prime-decider-primes-${Date.now()}.txt`;
  305.   a.click();
  306.   URL.revokeObjectURL(url);
  307.   appendToTerminal('Primes saved to .txt file');
  308. };
  309.  
  310. /* -----------------------------
  311.    Canvas waveform
  312. ------------------------------*/
  313. const canvas = document.getElementById('wave');
  314. const ctx = canvas.getContext('2d');
  315. let wavePhase = 0;
  316. function drawWave(amp=12){
  317.   const w = canvas.width;
  318.   const h = canvas.height;
  319.   ctx.clearRect(0,0,w,h);
  320.   ctx.fillStyle = 'rgba(110,231,247,0.04)';
  321.   ctx.beginPath();
  322.   for(let x=0;x<w;x++){
  323.    const v = Math.sin((x*0.03)+wavePhase) * Math.sin(wavePhase*0.1) * (amp/2) + (h/2);
  324.    if(x===0) ctx.moveTo(x,v); else ctx.lineTo(x,v);
  325.  }
  326.  ctx.lineTo(w,h); ctx.lineTo(0,h); ctx.closePath(); ctx.fill();
  327.  wavePhase += 0.14 * Math.max(0.5,state.progress/100);
  328. }
  329.  
  330. /* -----------------------------
  331.   UI helpers
  332. ------------------------------*/
  333. function updateRuntime() {
  334.  if (!state.startTime) {
  335.    runtimeEl.textContent = '00:00:00';
  336.    return;
  337.  }
  338.  let elapsed = (Date.now() - state.startTime.getTime()) / 1000;
  339.  let h = Math.floor(elapsed / 3600);
  340.  let m = Math.floor((elapsed % 3600) / 60);
  341.  let s = Math.floor(elapsed % 60);
  342.  runtimeEl.textContent = `${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`;
  343. }
  344.  
  345. function updateUI(){
  346.  bigPrime.textContent = state.primes.length ? state.primes.at(-1).toString() : '-';
  347.  primesFound.textContent = state.primes.length;
  348.  currentNEl.textContent = state.currentN.toString();
  349.  progressBar.style.width = `${state.progress}%`;
  350.  let curMethod = state.phase === 'calc' ? state.primaryMethod : state.verifyMethod;
  351.  let curId = curMethod ? curMethod.id : 'Idle';
  352.  calcMsg.textContent = `${state.phase} • ${curId} • ${Math.round(state.progress)}%`;
  353.  equationEl.textContent = curMethod ? curMethod.equation : '';
  354.  primeSub.textContent = `last calculated by ${state.primaryMethod?.id || 'none'}`;
  355.  // methods pills
  356.  methodList.innerHTML = '';
  357.  state.methods.forEach((m,i)=>{
  358.     const p = document.createElement('div');
  359.     p.className = 'method-pill' + (m.enabled? ' active':'');
  360.     p.textContent = m.id;
  361.     p.onclick = ()=>{ m.enabled = !m.enabled; updateUI(); }
  362.     methodList.appendChild(p);
  363.   });
  364.   updateRuntime();
  365. }
  366.  
  367. /* -----------------------------
  368.    Controls
  369. ------------------------------*/
  370. toggleBtn.onclick = ()=>{
  371.   if (!state.running) {
  372.     state.running = true;
  373.     if (!state.startTime) {
  374.       state.startTime = new Date();
  375.     }
  376.     toggleBtn.textContent = 'Pause';
  377.     toggleBtn.classList.add('primary');
  378.     appendToTerminal('Started prime hunting');
  379.     runLoop();
  380.   } else {
  381.     state.running = false;
  382.     toggleBtn.textContent = 'Start';
  383.     toggleBtn.classList.remove('primary');
  384.     appendToTerminal('Paused prime hunting');
  385.   }
  386. };
  387.  
  388. stepBtn.onclick = ()=> {
  389.   performOneCycle();
  390. };
  391.  
  392. /* -----------------------------
  393.    Run loop
  394. ------------------------------*/
  395. let loopHandle = null;
  396. function runLoop(){
  397.   if(!state.running) return;
  398.   const iterations = Math.max(1, state.speed);
  399.   (function frame(){
  400.     if(!state.running) return;
  401.     for(let i=0;i<iterations;i++){
  402.      performOneCycle();
  403.    }
  404.    drawWave();
  405.    updateUI();
  406.    loopHandle = requestAnimationFrame(frame);
  407.  })();
  408. }
  409.  
  410. /* performOneCycle */
  411. function performOneCycle(){
  412.  if (state.phase === 'calc' && state.progress === 0) {
  413.    const enabledMethods = state.methods.filter(m => m.enabled);
  414.     if (enabledMethods.length === 0) {
  415.       state.progress = 0;
  416.       updateUI();
  417.       return;
  418.     }
  419.     const idx = state.methodIndex % enabledMethods.length;
  420.     state.primaryMethod = enabledMethods[idx];
  421.     state.methodIndex++;
  422.     state.verifyMethod = null;
  423.   }
  424.  
  425.   let maxProg = state.phase === 'calc' ? 50 : 100;
  426.   let delta = Math.max(8, 6 + Math.random()*8) * state.speed / 2;
  427.   state.progress += delta;
  428.   state.progress = Math.min(maxProg, state.progress);
  429.  
  430.   let phaseLimit = state.phase === 'calc' ? 50 : 100;
  431.  
  432.   if (state.progress >= phaseLimit) {
  433.     if (state.phase === 'calc') {
  434.       setTimeout(() => {
  435.         const nStr = state.currentN.toString();
  436.         const isP = state.primaryMethod.fn(state.currentN);
  437.         if (!isP) {
  438.           state.currentN = state.currentN % 2n === 0n ? state.currentN + 1n : state.currentN + 2n;
  439.           state.progress = 0;
  440.           state.phase = 'calc';
  441.           const enabledMethods = state.methods.filter(m => m.enabled);
  442.           if (enabledMethods.length > 0) {
  443.             const idx = state.methodIndex % enabledMethods.length;
  444.             state.primaryMethod = enabledMethods[idx];
  445.             state.methodIndex++;
  446.           }
  447.         } else {
  448.           let candidates = state.methods.filter(m => m.enabled && m !== state.primaryMethod);
  449.           if (candidates.length === 0) candidates = [state.primaryMethod];
  450.           const vIdx = Math.floor(Math.random() * candidates.length);
  451.           state.verifyMethod = candidates[vIdx];
  452.           state.phase = 'verify';
  453.           state.progress = 50;
  454.         }
  455.         updateUI();
  456.       }, 10);
  457.     } else if (state.phase === 'verify') {
  458.       setTimeout(() => {
  459.         const nStr = state.currentN.toString();
  460.         const isV = state.verifyMethod.fn(state.currentN);
  461.         if (isV) {
  462.           const lastPrime = state.primes.at(-1) || 0n;
  463.           if (state.currentN > lastPrime && !state.primes.includes(state.currentN)) {
  464.            state.primes.push(state.currentN);
  465.             appendToTerminal(`PRIME FOUND: ${nStr}`);
  466.           }
  467.         }
  468.         state.currentN = state.currentN % 2n === 0n ? state.currentN + 1n : state.currentN + 2n;
  469.         state.progress = 0;
  470.         state.phase = 'calc';
  471.         const enabledMethods = state.methods.filter(m => m.enabled);
  472.         if (enabledMethods.length > 0) {
  473.           const idx = state.methodIndex % enabledMethods.length;
  474.           state.primaryMethod = enabledMethods[idx];
  475.           state.methodIndex++;
  476.         }
  477.         updateUI();
  478.       }, 10);
  479.     }
  480.   }
  481.  
  482.   if(state.progress < (state.phase === 'calc' ? 50 : 100)){
  483.    updateUI();
  484.  }
  485. }
  486.  
  487. /* -----------------------------
  488.   Prime helpers
  489. ------------------------------*/
  490. function trialDivision(n) {
  491.  n = BigInt(n);
  492.  if (n < 2n) return false;
  493.  if (n === 2n || n === 3n) return true;
  494.  if (n % 2n === 0n || n % 3n === 0n) return false;
  495.  let i = 5n;
  496.  let lim = bigSqrt(n);
  497.  while (i <= lim) {
  498.    if (n % i === 0n || n % (i + 2n) === 0n) return false;
  499.    i += 6n;
  500.  }
  501.  return true;
  502. }
  503.  
  504. function sieveOptimized(n) {
  505.  n = BigInt(n);
  506.  if (n < 2n) return false;
  507.  for (let p of state.primes) {
  508.    if (p * p > n) break;
  509.     if (n % p === 0n) return false;
  510.   }
  511.   return trialDivision(n);
  512. }
  513.  
  514. function sixKOptimization(n) {
  515.   return trialDivision(n);
  516. }
  517.  
  518. function fermatsTest(n) {
  519.   n = BigInt(n);
  520.   if (n < 2n) return false;
  521.  if (n <= 3n) return true;
  522.  if (n % 2n === 0n) return false;
  523.  const bases = [2n, 3n, 5n];
  524.  for (let base of bases) {
  525.    if (base >= n) break;
  526.     if (modPow(base, n - 1n, n) !== 1n) return false;
  527.   }
  528.   return true;
  529. }
  530.  
  531. function millerRabinTest(n) {
  532.   n = BigInt(n);
  533.   if (n < 2n) return false;
  534.  if (n === 2n || n === 3n) return true;
  535.  if (n % 2n === 0n) return false;
  536.  const witnesses = [2n, 3n, 5n, 7n, 11n];
  537.  let d = n - 1n;
  538.  let s = 0n;
  539.  while (d % 2n === 0n) {
  540.    d /= 2n;
  541.    s++;
  542.  }
  543.  for (let a of witnesses) {
  544.    if (a >= n) break;
  545.     let x = modPow(a, d, n);
  546.     if (x === 1n || x === n - 1n) continue;
  547.     let cont = false;
  548.     for (let r = 1n; r < s; r++) {
  549.      x = modPow(x, 2n, n);
  550.      if (x === n - 1n) {
  551.        cont = true;
  552.        break;
  553.      }
  554.    }
  555.    if (cont) continue;
  556.    return false;
  557.  }
  558.  return true;
  559. }
  560.  
  561. function wheelFactorization(n) {
  562.  n = BigInt(n);
  563.  if (n < 2n) return false;
  564.  if (n <= 5n) return true;
  565.  if (n % 2n === 0n || n % 3n === 0n || n % 5n === 0n) return false;
  566.  const offsets = [1n,7n,11n,13n,17n,19n,23n,29n];
  567.  let k = 0n;
  568.  let lim = bigSqrt(n);
  569.  while (true) {
  570.    let d = 30n * k;
  571.    let broke = true;
  572.    for (let r of offsets) {
  573.      let test = d + r;
  574.      if (test > lim) break;
  575.       if (n % test === 0n) return false;
  576.       broke = false;
  577.     }
  578.     if (broke) break;
  579.     k++;
  580.   }
  581.   return true;
  582. }
  583.  
  584. function jacobiSymbol(a, n) {
  585.   a = BigInt(a);
  586.   n = BigInt(n);
  587.   if (n <= 0n || n % 2n === 0n) return 0n;
  588.  a = a % n;
  589.  let result = 1n;
  590.  while (a !== 0n) {
  591.    while (a % 2n === 0n) {
  592.      a /= 2n;
  593.      let r = n % 8n;
  594.      if (r === 3n || r === 5n) result = -result;
  595.    }
  596.    [a, n] = [n, a];
  597.    if (a % 4n === 3n && n % 4n === 3n) result = -result;
  598.    a %= n;
  599.  }
  600.  return n === 1n ? result : 0n;
  601. }
  602.  
  603. function solovayStrassen(n) {
  604.  n = BigInt(n);
  605.  if (n < 2n) return false;
  606.  if (n === 2n || n === 3n) return true;
  607.  if (n % 2n === 0n) return false;
  608.  const k = 5;
  609.  for (let i = 0; i < k; i++) {
  610.    let a = BigInt(2 + Math.floor(Math.random() * Number(n - 3n)));
  611.    let legendre = jacobiSymbol(a, n);
  612.    if (legendre === 0n) return false;
  613.    let jacobi = legendre < 0n ? (n - 1n) : legendre;
  614.    if (modPow(a, (n - 1n)/2n, n) !== jacobi) return false;
  615.  }
  616.  return true;
  617. }
  618.  
  619. /* -----------------------------
  620.   Misc UI and keyboard
  621. ------------------------------*/
  622. function tick(){
  623.  drawWave();
  624.  updateUI();
  625.  requestAnimationFrame(tick);
  626. }
  627. tick();
  628.  
  629. document.addEventListener('keydown', (e)=>{
  630.   if(e.key==='p' || e.key==='P'){ toggleBtn.click(); }
  631.   if(e.key==='s' || e.key==='S'){ stepBtn.click(); }
  632. });
  633.  
  634. // Initialize terminal with initial primes
  635. state.primes.forEach(p => appendToTerminal(`PRIME: ${p.toString()}`));
  636.  
  637. /* startup */
  638. updateUI();
  639. </script>
  640. </body>
  641. </html>
  642.  
Advertisement
Add Comment
Please, Sign In to add comment