Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>The Prime Decider - Phoenix Edition</title>
- <style>
- /* CSS Reset and Global Styles */
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
- body {
- font-family: 'Courier New', monospace;
- background: linear-gradient(135deg, #0a0a0a 0%, #1a0033 50%, #330066 100%);
- color: #00ff88;
- min-height: 100vh;
- display: flex;
- justify-content: center;
- align-items: center;
- overflow: hidden;
- position: relative;
- }
- /* Phoenix Background Effects */
- body::before {
- content: '';
- position: absolute;
- width: 200%;
- height: 200%;
- background:
- radial-gradient(circle at 20% 80%, rgba(255, 100, 0, 0.15) 0%, transparent 50%),
- radial-gradient(circle at 80% 20%, rgba(255, 200, 0, 0.15) 0%, transparent 50%),
- radial-gradient(circle at 40% 40%, rgba(255, 50, 0, 0.1) 0%, transparent 50%);
- animation: phoenixFloat 25s ease-in-out infinite;
- }
- @keyframes phoenixFloat {
- 0%, 100% { transform: translate(0, 0) rotate(0deg) scale(1); }
- 25% { transform: translate(-30px, -30px) rotate(90deg) scale(1.1); }
- 50% { transform: translate(30px, -50px) rotate(180deg) scale(0.95); }
- 75% { transform: translate(-20px, 20px) rotate(270deg) scale(1.05); }
- }
- .phoenix-particles {
- position: absolute;
- top: 0; left: 0;
- width: 100%;
- height: 100%;
- overflow: hidden;
- pointer-events: none;
- }
- .phoenix-particle {
- position: absolute;
- width: 4px;
- height: 4px;
- background: radial-gradient(circle, rgba(255, 150, 0, 0.8), transparent);
- border-radius: 50%;
- animation: rise 4s linear infinite;
- }
- @keyframes rise {
- 0% { transform: translateY(100vh) scale(0); opacity: 0; }
- 10% { opacity: 1; }
- 90% { opacity: 1; }
- 100% { transform: translateY(-100vh) scale(1.5); opacity: 0; }
- }
- /* Main App Container */
- .container {
- background: rgba(10, 10, 30, 0.95);
- border-radius: 20px;
- padding: 30px;
- box-shadow:
- 0 0 100px rgba(255, 100, 0, 0.3),
- inset 0 0 50px rgba(255, 150, 0, 0.1);
- border: 2px solid rgba(255, 100, 0, 0.4);
- max-width: 1200px;
- width: 95%;
- position: relative;
- z-index: 10;
- display: grid;
- grid-template-columns: 1fr 450px;
- gap: 30px;
- max-height: 95vh;
- }
- .main-panel, .terminal-container {
- display: flex;
- flex-direction: column;
- gap: 15px;
- overflow: hidden;
- }
- h1 {
- text-align: center;
- font-size: 2.2em;
- text-shadow:
- 0 0 20px #ff6600, 0 0 40px #ff3300, 0 0 60px #ff0000;
- animation: phoenixPulse 3s ease-in-out infinite;
- background: linear-gradient(45deg, #ff6600, #ffaa00, #ff3300);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- background-clip: text;
- margin-bottom: 10px;
- }
- @keyframes phoenixPulse {
- 0%, 100% { filter: brightness(1); transform: scale(1); }
- 50% { filter: brightness(1.3); transform: scale(1.02); }
- }
- /* Terminal Window Styles */
- .terminal-container {
- background: #000000;
- border: 2px solid rgba(255, 100, 0, 0.5);
- border-radius: 10px;
- padding: 15px;
- box-shadow: inset 0 0 20px rgba(255, 100, 0, 0.2);
- height: calc(95vh - 60px);
- }
- .terminal-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding-bottom: 10px;
- border-bottom: 1px solid rgba(255, 100, 0, 0.3);
- flex-shrink: 0;
- }
- .terminal-title {
- color: #ffaa00;
- font-size: 1.1em;
- text-shadow: 0 0 10px rgba(255, 150, 0, 0.5);
- }
- .terminal-output {
- flex-grow: 1;
- background: #0a0a0a;
- padding: 10px;
- overflow-y: auto;
- font-size: 0.9em;
- color: #00ff88;
- border-radius: 5px;
- line-height: 1.6;
- white-space: pre-wrap;
- word-break: break-all;
- }
- .terminal-line { animation: fadeIn 0.3s ease; }
- .terminal-prime { color: #ffaa00; font-weight: bold; }
- .terminal-info { color: #888; font-style: italic; }
- .terminal-error { color: #ff3333; font-weight: bold; }
- @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
- /* General UI Component Styles */
- .display-card, .algorithm-info, .stats, .controls {
- background: rgba(0, 0, 0, 0.5);
- padding: 15px;
- border-radius: 10px;
- border: 1px solid rgba(255, 100, 0, 0.3);
- text-align: center;
- }
- #last-prime {
- font-size: 2.5em;
- color: #ffffff;
- text-shadow: 0 0 20px rgba(255, 150, 0, 0.7);
- word-break: break-all;
- }
- #prime-count-display { font-size: 1.1em; color: #ffaa00; }
- #algorithm-name { color: #ffff00; }
- #equation-display { color: #00ffff; font-size: 0.9em; margin-top: 5px; }
- .progress-bar-container {
- width: 100%; height: 30px; background: rgba(0, 0, 0, 0.5);
- border-radius: 15px; overflow: hidden; position: relative;
- border: 2px solid rgba(255, 100, 0, 0.3);
- }
- #progress-bar {
- height: 100%; width: 0%;
- background: linear-gradient(90deg, #ff6600 0%, #ffaa00 50%, #ff3300 100%);
- border-radius: 13px; transition: width 0.1s linear;
- }
- #progress-text {
- position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
- color: white; font-weight: bold; text-shadow: 1px 1px 2px black;
- }
- .controls { display: flex; justify-content: center; gap: 15px; flex-wrap: wrap; }
- button {
- padding: 10px 20px; font-size: 1em;
- background: linear-gradient(135deg, #ff6600, #ffaa00);
- color: #000; border: none; border-radius: 20px;
- cursor: pointer; font-weight: bold; transition: all 0.3s ease;
- box-shadow: 0 0 20px rgba(255, 100, 0, 0.3);
- }
- button:hover { transform: translateY(-2px); box-shadow: 0 5px 30px rgba(255, 100, 0, 0.5); }
- button.paused { background: linear-gradient(135deg, #cc0066, #ff3399); }
- .stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
- .stat-label { color: #888; font-size: 0.8em; }
- .stat-value { color: #ffaa00; font-weight: bold; word-break: break-all; }
- .info-text { color: #888; font-size: 0.8em; margin-top: auto; }
- input[type="file"] { display: none; }
- /* Scrollbar and Responsive Styles */
- ::-webkit-scrollbar { width: 8px; }
- ::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.3); }
- ::-webkit-scrollbar-thumb { background: rgba(255, 100, 0, 0.5); border-radius: 4px; }
- @media (max-width: 1024px) {
- body { align-items: flex-start; padding: 20px 0; height: auto; }
- .container { grid-template-columns: 1fr; max-height: none; }
- .terminal-container { height: 400px; }
- h1 { font-size: 1.8em; }
- #last-prime { font-size: 1.8em; }
- }
- </style>
- </head>
- <body>
- <div class="phoenix-particles" id="phoenixParticles"></div>
- <div class="container">
- <div class="main-panel">
- <h1>🔥 The Prime Decider - Phoenix Edition 🔥</h1>
- <div class="display-card">
- <div id="last-prime">N/A</div>
- <div id="prime-count-display">Primes Found: 0</div>
- </div>
- <div class="algorithm-info">
- <div id="algorithm-name">Awaiting Rebirth...</div>
- <div id="equation-display">...</div>
- </div>
- <div class="progress-bar-container">
- <div id="progress-bar"></div>
- <div id="progress-text">Paused</div>
- </div>
- <div class="controls">
- <button id="pause-button" onclick="togglePause()">Start</button>
- <button onclick="saveProgress()">💾 Save Phoenix</button>
- <button onclick="document.getElementById('fileInput').click()">📂 Load Phoenix</button>
- <input type="file" id="fileInput" accept=".txt" onchange="loadProgress(event)">
- </div>
- <div class="stats">
- <div>
- <div class="stat-label">Currently Checking</div>
- <div class="stat-value" id="current-number">1</div>
- </div>
- <div>
- <div class="stat-label">Runtime</div>
- <div class="stat-value" id="runtime">00:00:00</div>
- </div>
- </div>
- <div class="info-text">Press 'P' to Pause/Resume • Your hunt for primes is now eternal.</div>
- </div>
- <div class="terminal-container">
- <div class="terminal-header">
- <div class="terminal-title">>_ Phoenix Terminal</div>
- </div>
- <div class="terminal-output" id="terminal-output"></div>
- </div>
- </div>
- <script>
- // DOM Element References
- const lastPrimeEl = document.getElementById('last-prime');
- const primeCountDisplayEl = document.getElementById('prime-count-display');
- const currentNumberEl = document.getElementById('current-number');
- const algorithmNameEl = document.getElementById('algorithm-name');
- const equationDisplayEl = document.getElementById('equation-display');
- const progressBarEl = document.getElementById('progress-bar');
- const progressTextEl = document.getElementById('progress-text');
- const pauseButton = document.getElementById('pause-button');
- const terminalOutputEl = document.getElementById('terminal-output');
- const runtimeEl = document.getElementById('runtime');
- // State Management
- let state = {
- isPaused: true,
- currentNumber: 1n,
- primeCount: 0,
- lastPrime: 'N/A',
- algorithmIndex: 0,
- startTime: null,
- runtimeInterval: null,
- primesFound: [], // Array to store primes for terminal and saving
- };
- // =====================================================================
- // ## Primality Testing Algorithms & Helpers
- // =====================================================================
- function power(base, exp, mod) {
- let res = 1n;
- base %= mod;
- while (exp > 0) {
- if (exp % 2n === 1n) res = (res * base) % mod;
- base = (base * base) % mod;
- exp /= 2n;
- }
- return res;
- }
- const algorithms = [
- { name: "Trial Division", equation: "n % i != 0 for i in [5, √n]", fn: function(n) {
- if (n <= 1n) return false; if (n <= 3n) return true;
- if (n % 2n === 0n || n % 3n === 0n) return false;
- for (let i = 5n; i * i <= n; i = i + 6n) {
- if (n % i === 0n || n % (i + 2n) === 0n) return false;
- }
- return true;
- }},
- { name: "Fermat's Little Theorem", equation: "a^(n-1) ≡ 1 (mod n)", fn: function(n, k = 5) {
- if (n <= 1n || n === 4n) return false; if (n <= 3n) return true;
- for (let i = 0; i < k; i++) {
- let a = 2n + BigInt(Math.floor(Math.random() * Number(n > 4n ? n - 4n : 1n)));
- if (power(a, n - 1n, n) !== 1n) return false;
- }
- return true;
- }},
- { name: "Miller-Rabin Test", equation: "Probabilistic check with witnesses", fn: function(n, k = 5) {
- if (n <= 1n || n === 4n) return false; if (n <= 3n) return true;
- if (n % 2n === 0n) return false;
- let d = n - 1n; while (d % 2n === 0n) d /= 2n;
- for (let i = 0; i < k; i++) {
- let a = 2n + BigInt(Math.floor(Math.random() * Number(n > 4n ? n - 4n : 1n)));
- let x = power(a, d, n);
- if (x === 1n || x === n - 1n) continue;
- let isWitness = true;
- let dCopy = d;
- while (dCopy < n - 1n) {
- x = (x * x) % n;
- if (x === n - 1n) { isWitness = false; break; }
- dCopy *= 2n;
- }
- if (isWitness) return false;
- }
- return true;
- }}
- ];
- const verificationAlgorithm = algorithms[0]; // Always verify with the most reliable
- // =====================================================================
- // ## Core Application & UI Logic
- // =====================================================================
- function addToTerminal(message, type = '') {
- const line = document.createElement('div');
- line.className = `terminal-line ${type}`;
- if (type === 'terminal-prime') {
- line.innerHTML = `> New Prime Discovered: <span class="terminal-prime">${message.toLocaleString()}</span>`;
- } else {
- line.textContent = `// ${message}`;
- }
- terminalOutputEl.appendChild(line);
- terminalOutputEl.scrollTop = terminalOutputEl.scrollHeight;
- }
- function updateUI() {
- primeCountDisplayEl.textContent = `Primes Found: ${state.primeCount.toLocaleString()}`;
- lastPrimeEl.textContent = typeof state.lastPrime === 'bigint' ? state.lastPrime.toLocaleString() : state.lastPrime;
- currentNumberEl.textContent = state.currentNumber.toLocaleString();
- }
- function updateRuntime() {
- if (!state.startTime || state.isPaused) return;
- const elapsed = Math.floor((Date.now() - state.startTime) / 1000);
- const hours = String(Math.floor(elapsed / 3600)).padStart(2, '0');
- const minutes = String(Math.floor((elapsed % 3600) / 60)).padStart(2, '0');
- const seconds = String(elapsed % 60).padStart(2, '0');
- runtimeEl.textContent = `${hours}:${minutes}:${seconds}`;
- }
- function processNextNumber() {
- if (state.isPaused) return;
- state.currentNumber++;
- currentNumberEl.textContent = state.currentNumber.toLocaleString();
- const calculationAlgo = algorithms[state.algorithmIndex];
- algorithmNameEl.textContent = `Calculating: ${calculationAlgo.name}`;
- equationDisplayEl.textContent = calculationAlgo.equation;
- progressTextEl.textContent = 'Calculating...';
- const isPotentiallyPrime = calculationAlgo.fn(state.currentNumber);
- // Animate first half (Calculation)
- progressBarEl.style.width = '50%';
- setTimeout(() => {
- if (state.isPaused) return;
- algorithmNameEl.textContent = `Verifying: ${verificationAlgorithm.name}`;
- progressTextEl.textContent = 'Error-Checking...';
- const isConfirmedPrime = verificationAlgorithm.fn(state.currentNumber);
- // Animate second half (Verification)
- progressBarEl.style.width = '100%';
- setTimeout(() => {
- if (state.isPaused) return;
- if (isConfirmedPrime) {
- state.primeCount++;
- state.lastPrime = state.currentNumber;
- state.primesFound.push(state.currentNumber);
- addToTerminal(state.currentNumber, 'terminal-prime');
- }
- state.algorithmIndex = (state.algorithmIndex + 1) % algorithms.length;
- updateUI();
- progressBarEl.style.width = '0%';
- setTimeout(processNextNumber, 0); // Next cycle
- }, 200);
- }, 200);
- }
- function togglePause() {
- state.isPaused = !state.isPaused;
- if (state.isPaused) {
- pauseButton.textContent = 'Resume';
- pauseButton.classList.add('paused');
- progressTextEl.textContent = 'Paused';
- algorithmNameEl.textContent = 'Calculations Paused';
- } else {
- if (state.startTime === null) { // First start
- state.startTime = Date.now();
- state.runtimeInterval = setInterval(updateRuntime, 1000);
- }
- pauseButton.textContent = 'Pause';
- pauseButton.classList.remove('paused');
- updateUI();
- processNextNumber();
- }
- }
- // =====================================================================
- // ## Save & Load "Phoenix State" Logic
- // =====================================================================
- function saveProgress() {
- if (state.primesFound.length === 0) {
- addToTerminal("No primes to save.", "terminal-error");
- return;
- }
- const wasPaused = state.isPaused;
- if (!wasPaused) togglePause(); // Pause to prevent data race
- const fileContent = state.primesFound.join('\t');
- const blob = new Blob([fileContent], { type: 'text/plain;charset=utf-8' });
- const a = document.createElement('a');
- a.href = URL.createObjectURL(blob);
- a.download = `prime_decider_phoenix_save_${Date.now()}.txt`;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(a.href);
- addToTerminal("Phoenix state saved to file.");
- if (!wasPaused) togglePause(); // Resume if it was running
- }
- function loadProgress(event) {
- const file = event.target.files[0];
- if (!file) return;
- if (!state.isPaused) togglePause(); // Force pause during load
- const reader = new FileReader();
- reader.onload = (e) => {
- try {
- const content = e.target.result;
- const primeStrings = content.split('\t').filter(s => s.trim() !== '');
- if (primeStrings.length === 0) throw new Error("File is empty or invalid.");
- // Reset and load new state
- terminalOutputEl.innerHTML = '';
- addToTerminal(`Phoenix rising from ashes of '${file.name}'...`);
- const loadedPrimes = primeStrings.map(s => BigInt(s.trim()));
- state.primesFound = loadedPrimes;
- state.primeCount = loadedPrimes.length;
- state.lastPrime = loadedPrimes[loadedPrimes.length - 1];
- state.currentNumber = state.lastPrime;
- // Repopulate terminal (show last 100 for performance)
- const displayPrimes = loadedPrimes.slice(-100);
- addToTerminal(`Loaded ${loadedPrimes.length} primes. Displaying last ${displayPrimes.length}.`);
- displayPrimes.forEach(p => addToTerminal(p, 'terminal-prime'));
- updateUI();
- addToTerminal(`Ready to seek primes after ${state.lastPrime.toLocaleString()}.`);
- } catch (error) {
- addToTerminal(`Error loading file: ${error.message}`, 'terminal-error');
- console.error("Load error:", error);
- } finally {
- // Reset the file input to allow loading the same file again
- event.target.value = '';
- }
- };
- reader.readAsText(file);
- }
- // =====================================================================
- // ## Initialization
- // =====================================================================
- function generatePhoenixParticles() {
- const container = document.getElementById('phoenixParticles');
- for (let i = 0; i < 30; i++) {
- const particle = document.createElement('div');
- particle.className = 'phoenix-particle';
- particle.style.left = `${Math.random() * 100}%`;
- particle.style.animationDelay = `${Math.random() * 4}s`;
- particle.style.animationDuration = `${2 + Math.random() * 3}s`;
- container.appendChild(particle);
- }
- }
- window.onload = () => {
- generatePhoenixParticles();
- addToTerminal("Phoenix Prime Decider initialized...");
- addToTerminal("Awaiting the command to rise.");
- updateUI();
- };
- window.addEventListener('keydown', (e) => {
- if (e.key.toLowerCase() === 'p') {
- e.preventDefault();
- togglePause();
- }
- });
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment