📂 File Browser

/NP
🌙 Dark Mode
🎯 Quick Launch:

📁 Directories

📄 Files

🐘 index.php
▶ Open 📄 View Source
📜 script.js
▶ Open 📄 View Source
🎨 style.css
▶ Open 📄 View Source

📄 Source: index.php

<?php
// index.php - VERSION FINALĂ (CU EVALUARE CORECTĂ 100%)

session_start();

// ========== FUNCȚIE DE EVALUARE MATEMATICĂ ==========
function evaluateExpression($expr) {
    // Curățăm expresia
    $expr = trim($expr);
    if ($expr === '') return false;
    
    // PASUL CHEIE: Înlocuim constantele, dar PROTEJĂM notația științifică
    
    // 1. Protejăm temporar numerele în notație științifică (ex: 1.2e5, 3E-4, 17e3)
    //    Acestea vor fi înlocuite cu placeholder-uri
    $scientificPlaceholders = [];
    $expr = preg_replace_callback('/\b\d+(?:\.\d+)?[eE][+-]?\d+\b/', function($matches) use (&$scientificPlaceholders) {
        $key = '###SCI_' . count($scientificPlaceholders) . '###';
        $scientificPlaceholders[$key] = $matches[0];
        return $key;
    }, $expr);
    
    // 2. Înlocuim 'e' doar când e o constantă separată (nu atașată de un număr)
    //    Cazuri: e, e+5, (e), e*10, 2*e, etc.
    //    Folosim regex care caută 'e' precedat și urmat de non-cifre/non-litere
    $expr = preg_replace('/(?<![a-zA-Z0-9])e(?![a-zA-Z0-9])/i', M_E, $expr);
    
    // 3. Înlocuim 'pi' și 'π' (aceștia nu au problema cu notația științifică)
    $expr = preg_replace('/(?<![a-zA-Z0-9])pi(?![a-zA-Z0-9])/i', M_PI, $expr);
    $expr = str_replace('π', M_PI, $expr);
    
    // 4. Restaurăm placeholder-ele cu numerele în notație științifică originală
    foreach ($scientificPlaceholders as $key => $value) {
        $expr = str_replace($key, $value, $expr);
    }
    
    // Eliminăm spațiile
    $expr = preg_replace('/\s+/', '', $expr);
    
    // Validare caractere permise (acum 'e' poate apărea doar în notația științifică restaurată)
    if (!preg_match('/^[0-9+\-*\/\(\)\.eE]+$/', $expr)) {
        return false;
    }
    
    // Evaluare sigură
    try {
        $result = eval("return ($expr);");
        if (!is_numeric($result)) return false;
        return $result;
    } catch (Throwable $e) {
        return false;
    }
}

// ========== RESTUL FUNCȚIILOR RĂMÂN LA FEL ==========
function getFibonacciUpToN($limit) {
    if ($limit < 0) return [];
    $fib = [];
    $a = 0; $b = 1;
    if ($limit >= 0) $fib[] = 0;
    if ($limit >= 1) $fib[] = 1;
    while (true) {
        $next = $a + $b;
        if ($next > $limit) break;
        $fib[] = $next;
        $a = $b;
        $b = $next;
    }
    return $fib;
}

function getEvenNumbers($limit) {
    $evens = [];
    for ($i = 0; $i <= $limit; $i += 2) $evens[] = $i;
    return $evens;
}

function getOddNumbers($limit) {
    $odds = [];
    for ($i = 1; $i <= $limit; $i += 2) $odds[] = $i;
    return $odds;
}

function getPerfectSquares($limit) {
    $squares = [];
    for ($i = 1; $i * $i <= $limit; $i++) {
        $squares[] = $i * $i;
    }
    return $squares;
}

function getPerfectCubes($limit) {
    $cubes = [];
    for ($i = 1; $i * $i * $i <= $limit; $i++) {
        $cubes[] = $i * $i * $i;
    }
    return $cubes;
}

function getPowersOfTwo($limit) {
    $powers = [];
    $val = 1;
    while ($val <= $limit) {
        $powers[] = $val;
        $val *= 2;
    }
    return $powers;
}

function getMultiplesOfThree($limit) {
    $multiples = [];
    for ($i = 3; $i <= $limit; $i += 3) $multiples[] = $i;
    return $multiples;
}

function getPrimesUpTo($limit) {
    if ($limit < 2) return [];
    $sieve = array_fill(0, floor($limit) + 1, true);
    $sieve[0] = $sieve[1] = false;
    for ($i = 2; $i * $i <= $limit; $i++) {
        if ($sieve[$i]) {
            for ($j = $i * $i; $j <= $limit; $j += $i) {
                $sieve[$j] = false;
            }
        }
    }
    $primes = [];
    for ($i = 2; $i <= $limit; $i++) {
        if ($sieve[$i]) $primes[] = $i;
    }
    return $primes;
}

function getArithmeticProgression($limit, $firstTerm = 1, $ratio = 4) {
    $seq = [];
    $current = $firstTerm;
    while ($current <= $limit) {
        $seq[] = $current;
        $current += $ratio;
    }
    return $seq;
}

function getGeometricProgression($limit, $firstTerm = 1, $ratio = 2) {
    $seq = [];
    $current = $firstTerm;
    while ($current <= $limit) {
        $seq[] = $current;
        $current *= $ratio;
    }
    return $seq;
}

function getLeonardoNumbers($limit) {
    if ($limit < 0) return [];
    $leo = [];
    $a = 1; $b = 1;
    if ($limit >= 1) $leo[] = 1;
    if ($limit >= 1 && count($leo) < 2 && 1 <= $limit) $leo[] = 1;
    while (true) {
        $next = $a + $b + 1;
        if ($next > $limit) break;
        $leo[] = $next;
        $a = $b;
        $b = $next;
    }
    $unique = [];
    $seen = [];
    foreach ($leo as $val) {
        if (!in_array($val, $seen)) {
            $seen[] = $val;
            $unique[] = $val;
        }
    }
    return $unique;
}

function getTribonacciNumbers($limit) {
    if ($limit < 0) return [];
    $trib = [];
    $a = 0; $b = 0; $c = 1;
    if ($limit >= 0) $trib[] = 0;
    if ($limit >= 0 && count($trib) == 1 && 0 <= $limit) $trib[] = 0;
    if ($limit >= 1) $trib[] = 1;
    while (true) {
        $next = $a + $b + $c;
        if ($next > $limit) break;
        $trib[] = $next;
        $a = $b;
        $b = $c;
        $c = $next;
    }
    return array_values(array_unique($trib));
}

function getFactorials($limit) {
    $factorials = [];
    $fact = 1;
    $i = 0;
    while ($fact <= $limit) {
        $factorials[] = $fact;
        $i++;
        if ($i > 20) break;
        $fact *= $i;
    }
    return $factorials;
}

function formatSequence($arr, $maxDisplay = 20) {
    if (empty($arr)) return "∅ (niciun element)";
    $displayArr = array_slice($arr, 0, $maxDisplay);
    $str = implode(", ", $displayArr);
    if (count($arr) > $maxDisplay) {
        $str .= sprintf(", … (%d mai multe)", count($arr) - $maxDisplay);
    }
    return $str;
}

// Procesarea cererii
$error = "";
$sequences = null;
$submittedNumber = 50;
$rawInput = "50";
$evaluatedValue = 50;

if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["number"])) {
    $rawInput = trim($_POST["number"]);
    
    $evaluated = evaluateExpression($rawInput);
    
    if ($evaluated !== false && $evaluated > 0) {
        $evaluatedValue = $evaluated;
        $submittedNumber = max(1, (int)round($evaluated));
        $N = $submittedNumber;
        
        if ($N > 10000) {
            $error = "Numărul este prea mare (maxim 10000). Te rog introdu o valoare mai mică.";
        } else {
            $sequences = [
                'fibonacci' => getFibonacciUpToN($N),
                'tribonacci' => getTribonacciNumbers($N),
                'leonardo' => getLeonardoNumbers($N),
                'even' => getEvenNumbers($N),
                'odd' => getOddNumbers($N),
                'squares' => getPerfectSquares($N),
                'cubes' => getPerfectCubes($N),
                'powersOfTwo' => getPowersOfTwo($N),
                'multiplesOf3' => getMultiplesOfThree($N),
                'primes' => getPrimesUpTo($N),
                'arithProg' => getArithmeticProgression($N, 1, 4),
                'geoProg' => getGeometricProgression($N, 1, 2),
                'factorials' => getFactorials($N)
            ];
        }
    } else {
        $error = "Expresie invalidă. Te rog introdu un număr sau o expresie validă (ex: 50, 12+4, 35/2, 5*10, e, pi, 3e5, 12e+2, 6pi/2+30).";
    }
} else {
    $N = 50;
    $sequences = [
        'fibonacci' => getFibonacciUpToN($N),
        'tribonacci' => getTribonacciNumbers($N),
        'leonardo' => getLeonardoNumbers($N),
        'even' => getEvenNumbers($N),
        'odd' => getOddNumbers($N),
        'squares' => getPerfectSquares($N),
        'cubes' => getPerfectCubes($N),
        'powersOfTwo' => getPowersOfTwo($N),
        'multiplesOf3' => getMultiplesOfThree($N),
        'primes' => getPrimesUpTo($N),
        'arithProg' => getArithmeticProgression($N, 1, 4),
        'geoProg' => getGeometricProgression($N, 1, 2),
        'factorials' => getFactorials($N)
    ];
}
?>

<!DOCTYPE html>
<html lang="ro">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Explorator de Șiruri Matematice</title>
    <link rel="stylesheet" href="style.css">
    <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,300;400;600;700;800&display=swap" rel="stylesheet">
    <style>
        .examples-panel {
            background: var(--code-bg);
            border-radius: 1rem;
            padding: 0.75rem 1rem;
            margin-top: 1rem;
            font-size: 0.8rem;
        }
        .examples-panel h4 {
            margin-bottom: 0.5rem;
            font-size: 0.85rem;
        }
        .examples-grid {
            display: flex;
            flex-wrap: wrap;
            gap: 0.5rem;
        }
        .example-chip {
            background: var(--bg-card);
            border: 1px solid var(--border-color);
            padding: 0.25rem 0.75rem;
            border-radius: 2rem;
            cursor: pointer;
            transition: all 0.2s;
            font-family: monospace;
            font-size: 0.75rem;
        }
        .example-chip:hover {
            background: var(--btn-bg);
            color: white;
            transform: scale(1.02);
        }
        .evaluated-badge {
            background: linear-gradient(135deg, #3b82f6, #8b5cf6);
            color: white;
            padding: 0.25rem 0.75rem;
            border-radius: 2rem;
            font-size: 0.7rem;
            margin-left: 0.5rem;
        }
        .test-section {
            margin-top: 1rem;
            padding: 0.75rem;
            background: rgba(59,130,246,0.1);
            border-radius: 1rem;
            font-size: 0.75rem;
        }
    </style>
</head>
<body>
    <div class="theme-switcher">
        <button class="theme-btn" data-theme="light">☀️</button>
        <button class="theme-btn" data-theme="dark">🌙</button>
        <button class="theme-btn" data-theme="ocean">🌊</button>
        <button class="theme-btn" data-theme="sunset">🌅</button>
    </div>

    <div class="container">
        <header class="header">
            <h1>
                <span class="icon">📐</span>
                Explorator de Șiruri Matematice
            </h1>
            <p class="subhead">
                ✨ Evaluare matematică avansată + șiruri celebre
            </p>
        </header>

        <div class="form-card">
            <form method="POST" action="" id="mainForm">
                <div class="input-group">
                    <div class="input-field">
                        <label for="number">
                            🧮 Expresie matematică (N)
                            <span class="tooltip">ℹ️ Acceptă: numere, constante (e, pi), operații (+, -, *, /), notație științifică (1.2e5, 17e3)</span>
                        </label>
                        <input type="text" 
                               name="number" 
                               id="number" 
                               value="<?php echo htmlspecialchars($rawInput); ?>" 
                               placeholder="Ex: 50, 12+4, 35/2, e, pi, 17e, 12e+2, 6pi/2+30"
                               autocomplete="off">
                    </div>
                    <button type="submit" class="btn-primary">
                        <span class="btn-icon">✨</span>
                        Generează șiruri
                    </button>
                </div>
                <?php if ($error): ?>
                    <div class="error-message">
                        ⚠️ <?php echo htmlspecialchars($error); ?>
                    </div>
                <?php endif; ?>
                
                <div class="examples-panel">
                    <h4>📋 Click pe orice exemplu pentru a testa:</h4>
                    <div class="examples-grid">
                        <span class="example-chip" data-expr="50">50</span>
                        <span class="example-chip" data-expr="12+4">12+4</span>
                        <span class="example-chip" data-expr="35/2">35/2 = 17.5</span>
                        <span class="example-chip" data-expr="5*10">5*10</span>
                        <span class="example-chip" data-expr="e">e ≈ 2.718</span>
                        <span class="example-chip" data-expr="pi">π ≈ 3.141</span>
                        <span class="example-chip" data-expr="17e">17e ≈ 46.2</span>
                        <span class="example-chip" data-expr="12e+2">12e+2 = 1200</span>
                        <span class="example-chip" data-expr="6pi/2+30">6π/2+30 ≈ 39.42</span>
                        <span class="example-chip" data-expr="e*10+5">e·10+5 ≈ 32.18</span>
                        <span class="example-chip" data-expr="2e3">2e3 = 2000</span>
                        <span class="example-chip" data-expr="1.5e-1">1.5e-1 = 0.15</span>
                    </div>
                </div>
            </form>
            <?php if ($submittedNumber && !$error): ?>
                <div class="info-badge">
                    📊 Afișează șiruri cu elemente ≤ <strong><?php echo number_format($submittedNumber, 0, ',', '.'); ?></strong>
                    <?php if (abs($evaluatedValue - $submittedNumber) > 0.0001): ?>
                        <span class="evaluated-badge">evaluat: <?php echo round($evaluatedValue, 6); ?></span>
                    <?php endif; ?>
                </div>
            <?php endif; ?>
        </div>

        <div class="stats-bar">
            <div class="stat-item">
                <span class="stat-value"><?php echo count($sequences ?? []); ?></span>
                <span class="stat-label">șiruri generate</span>
            </div>
            <div class="stat-item">
                <span class="stat-value" id="totalElements">0</span>
                <span class="stat-label">elemente totale</span>
            </div>
            <div class="stat-item">
                <span class="stat-value">≤ <?php echo number_format($submittedNumber, 0, ',', '.'); ?></span>
                <span class="stat-label">valoare maximă</span>
            </div>
        </div>

        <div class="sequences-grid" id="sequencesGrid">
            <?php if ($sequences): 
                $sequenceConfigs = [
                    'fibonacci' => ['title' => '🐚 Șirul lui Fibonacci', 'icon' => 'Fibonacci', 'desc' => 'Fₙ = Fₙ₋₁ + Fₙ₋₂', 'color' => 'gold'],
                    'tribonacci' => ['title' => '🔷 Șirul Tribonacci', 'icon' => 'Tribonacci', 'desc' => 'Tₙ = Tₙ₋₁ + Tₙ₋₂ + Tₙ₋₃', 'color' => 'blue'],
                    'leonardo' => ['title' => '🧠 Șirul lui Leonardo', 'icon' => 'Leonardo', 'desc' => 'Lₙ = Lₙ₋₁ + Lₙ₋₂ + 1', 'color' => 'purple'],
                    'even' => ['title' => '🟢 Numere pare', 'icon' => 'Par', 'desc' => '2k', 'color' => 'green'],
                    'odd' => ['title' => '🔵 Numere impare', 'icon' => 'Impar', 'desc' => '2k+1', 'color' => 'cyan'],
                    'squares' => ['title' => '⬛ Pătrate perfecte', 'icon' => 'n²', 'desc' => 'n²', 'color' => 'red'],
                    'cubes' => ['title' => '🧊 Cuburi perfecte', 'icon' => 'n³', 'desc' => 'n³', 'color' => 'orange'],
                    'powersOfTwo' => ['title' => '⚡ Puteri ale lui 2', 'icon' => '2ⁿ', 'desc' => '2ᵏ', 'color' => 'yellow'],
                    'multiplesOf3' => ['title' => '✖️ Multipli ai lui 3', 'icon' => '3k', 'desc' => '3·k', 'color' => 'teal'],
                    'primes' => ['title' => '🔷 Numere prime', 'icon' => 'Prime', 'desc' => 'Numere cu exact 2 divizori', 'color' => 'indigo'],
                    'arithProg' => ['title' => '📈 Progresie aritmetică', 'icon' => 'r=4', 'desc' => '1, 5, 9, 13...', 'color' => 'pink'],
                    'geoProg' => ['title' => '📊 Progresie geometrică', 'icon' => 'r=2', 'desc' => '1, 2, 4, 8...', 'color' => 'rose'],
                    'factorials' => ['title' => '! Factoriale', 'icon' => 'n!', 'desc' => '1, 1, 2, 6, 24...', 'color' => 'slate']
                ];
                
                $totalElements = 0;
                foreach ($sequenceConfigs as $key => $config):
                    $seq = $sequences[$key] ?? [];
                    $count = count($seq);
                    $totalElements += $count;
                    $formatted = formatSequence($seq);
                    $fullSequence = implode(", ", $seq);
                ?>
                    <div class="sequence-card" data-color="<?php echo $config['color']; ?>">
                        <div class="card-header">
                            <div class="card-title">
                                <?php echo $config['title']; ?>
                                <span class="card-badge"><?php echo $config['icon']; ?></span>
                            </div>
                            <div class="card-meta">
                                <span class="element-count">📊 <?php echo $count; ?> elemente</span>
                            </div>
                        </div>
                        <div class="card-desc"><?php echo $config['desc']; ?></div>
                        <div class="sequence-content">
                            <span class="sequence-label">Șir:</span>
                            <div class="sequence-values" data-full="<?php echo htmlspecialchars($fullSequence); ?>">
                                <?php echo htmlspecialchars($formatted); ?>
                            </div>
                        </div>
                        <?php if ($count > 20): ?>
                            <div class="card-footer">
                                <button class="expand-btn" onclick="toggleSequence(this)">📋 Afișează toate</button>
                            </div>
                        <?php endif; ?>
                    </div>
                <?php 
                endforeach;
                ?>
                <script>document.getElementById('totalElements').textContent = '<?php echo $totalElements; ?>';</script>
            <?php else: ?>
                <div class="empty-state">
                    <div class="empty-icon">🔢</div>
                    <h3>Niciun șir generat</h3>
                    <p>Introdu o expresie matematică în formularul de mai sus pentru a genera șirurile.</p>
                </div>
            <?php endif; ?>
        </div>
        
        <footer class="footer">
            <p>⚡ Șirurile sunt generate până la valoarea N (elemente ≤ N, rotunjit la întreg)</p>
            <p>📐 Constante: <code>e</code> = 2.71828..., <code>pi</code> / <code>π</code> = 3.14159...</p>
            <p>🔢 Notație științifică: <code>17e</code> = 17×e, <code>12e+2</code> = 12×10² = 1200, <code>2e3</code> = 2000</p>
        </footer>
    </div>

    <script>
        // Teme
        (function() {
            const savedTheme = localStorage.getItem('math-sequence-theme');
            if (savedTheme) document.documentElement.setAttribute('data-theme', savedTheme);
            else document.documentElement.setAttribute('data-theme', 'light');
            
            document.querySelectorAll('.theme-btn').forEach(btn => {
                btn.addEventListener('click', function() {
                    const theme = this.getAttribute('data-theme');
                    document.documentElement.setAttribute('data-theme', theme);
                    localStorage.setItem('math-sequence-theme', theme);
                });
            });
        })();
        
        // Expand/Collapse
        window.toggleSequence = function(button) {
            const card = button.closest('.sequence-card');
            const valuesDiv = card.querySelector('.sequence-values');
            const fullSequence = valuesDiv.getAttribute('data-full');
            if (!fullSequence) return;
            
            if (button.textContent.includes('Afișează toate')) {
                if (!valuesDiv.getAttribute('data-short')) {
                    valuesDiv.setAttribute('data-short', valuesDiv.textContent);
                }
                valuesDiv.textContent = fullSequence;
                button.textContent = '📖 Arată mai puțin';
            } else {
                const shortText = valuesDiv.getAttribute('data-short') || 
                    fullSequence.split(', ').slice(0, 20).join(', ') + ', …';
                valuesDiv.textContent = shortText;
                button.textContent = '📋 Afișează toate';
            }
        };
        
        // Fade-in
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    entry.target.style.opacity = '1';
                    entry.target.style.transform = 'translateY(0)';
                    observer.unobserve(entry.target);
                }
            });
        }, { threshold: 0.1 });
        
        document.querySelectorAll('.sequence-card').forEach(card => {
            card.style.opacity = '0';
            card.style.transform = 'translateY(20px)';
            card.style.transition = 'all 0.5s ease';
            observer.observe(card);
        });
        
        // Click pe exemple - setează valoarea în input
        document.querySelectorAll('.example-chip').forEach(chip => {
            chip.addEventListener('click', function() {
                const expr = this.getAttribute('data-expr');
                const input = document.getElementById('number');
                if (input && expr) {
                    input.value = expr;
                    // Opțional: auto-submit
                    // document.getElementById('mainForm').submit();
                }
            });
        });
        
        // Salvare ultimul număr
        function saveLastNumber() {
            const lastNumber = document.getElementById('number')?.value;
            if (lastNumber && lastNumber !== '') localStorage.setItem('last-number', lastNumber);
        }
        window.addEventListener('beforeunload', saveLastNumber);
    </script>
</body>
</html>
← Back