"""
Watkins Spectral Kaleidoscope — Integer Sequences
==================================================

The complete integer content of the Watkins Spectral Kaleidoscope.
Nine sequences arising from quantum stabilizer weight-enumerators
parametrized by the golden ratio.

┌─────┬─────────────────────────────┬──────────┬───────────┐
│  #  │ Sequence                   │ σ-param  │ OEIS     │
├─────┼─────────────────────────────┼──────────┼───────────┤
│  1  │ Cycle L-B numerators       │ 0       │ A393329  │
│  2  │ Mersenne numerators        │ 0       │ A394248  │
│  3  │ Mersenne-factorial GCD     │ 0       │ A394249  │
│  4  │ Lucas numerators           │ 1       │ (pending)│
│  5  │ Lucas-factorial GCD        │ 1       │ (pending)│
│  6  │ Mersenne-Lucas GCD         │ 0∩1     │ (pending)│
│  7  │ Binary Preservation        │ bridge  │ (new)    │
│  8  │ Cross-GCD                  │ bridge  │ (new)    │
│  9  │ Weight-Enumerator Moments  │ trace   │ A005248  │
└─────┴─────────────────────────────┴──────────┴───────────┘

© 2024-2026 Dustin Watkins & DataSphere AI
"""

from math import gcd, factorial
from functools import lru_cache
from typing import List, Dict

__all__ = [
    'lucas', 'fibonacci', 'mersenne', 'popcount',
    'seq1_cycle_lb_numerator', 'seq2_mersenne_numerator', 'seq3_mersenne_gcd',
    'seq4_lucas_numerator', 'seq5_lucas_gcd', 'seq6_mersenne_lucas_gcd',
    'seq7_binary_preservation', 'seq8_cross_gcd', 'seq9_weight_moments',
    'generate_all_sequences', 'verify_pairings', 'find_seq8_spikes',
]

# ════════════════════════════════════════════════════════════════════════════════
# FUNDAMENTAL SEQUENCES
# ════════════════════════════════════════════════════════════════════════════════

@lru_cache(maxsize=1024)
def lucas(n: int) -> int:
    """Lucas number L(n) = φ^n + ψ^n."""
    if n == 0: return 2
    if n == 1: return 1
    a, b = 2, 1
    for _ in range(n - 1):
        a, b = b, a + b
    return b

@lru_cache(maxsize=1024)
def fibonacci(n: int) -> int:
    """Fibonacci number F(n)."""
    if n == 0: return 0
    if n == 1: return 1
    a, b = 0, 1
    for _ in range(n - 1):
        a, b = b, a + b
    return b

def mersenne(n: int) -> int:
    """Mersenne number M(n) = 2^n - 1."""
    return (1 << n) - 1

def popcount(x: int) -> int:
    """Count set bits (Hamming weight)."""
    return bin(x).count('1')

# ════════════════════════════════════════════════════════════════════════════════
# KALEIDOSCOPE SEQUENCES
# ════════════════════════════════════════════════════════════════════════════════

def seq1_cycle_lb_numerator(n: int) -> int:
    """A393329: Cycle Lagrange-Burmann numerators (σ=0)."""
    if n == 0: return 1
    M = mersenne(n + 1)
    return M // gcd(M, factorial(n + 1))

def seq2_mersenne_numerator(n: int) -> int:
    """A394248: Reduced numerators of (2^{n+2}-1)/(n+1)!."""
    M = mersenne(n + 2)
    return M // gcd(M, factorial(n + 1))

def seq3_mersenne_gcd(n: int) -> int:
    """A394249: gcd(2^{n+2}-1, (n+1)!)."""
    return gcd(mersenne(n + 2), factorial(n + 1))

def seq4_lucas_numerator(n: int) -> int:
    """Reduced numerators of L(n+1)/(n+1)!."""
    L = lucas(n + 1)
    return L // gcd(L, factorial(n + 1))

def seq5_lucas_gcd(n: int) -> int:
    """gcd(L(n+1), (n+1)!)."""
    return gcd(lucas(n + 1), factorial(n + 1))

def seq6_mersenne_lucas_gcd(n: int) -> int:
    """gcd(2^n - 1, L(n)) — Mersenne-Lucas interference.

    Divisibility rules (CRT-derived):
      - 3 | a(n) iff n ≡ 2 (mod 4)
      - 7 | a(n) iff n ≡ 12 (mod 24)
      - 31 | a(n) iff n ≡ 15 (mod 30)
    """
    if n == 0: return 2
    return gcd(mersenne(n), lucas(n))

def seq7_binary_preservation(n: int) -> int:
    """popcount(seq1(n) XOR seq4(n)) — Hamming distance across Watkins Bridge."""
    return popcount(seq1_cycle_lb_numerator(n) ^ seq4_lucas_numerator(n))

def seq8_cross_gcd(n: int) -> int:
    """gcd(seq1(n), seq4(n)) — shared primes across Mersenne/Lucas numerators.

    Extremely sparse; all spike values (>1) are prime.
    """
    return gcd(seq1_cycle_lb_numerator(n), seq4_lucas_numerator(n))

def seq9_weight_moments(k: int) -> int:
    """L(2k) = trace(T*^k) — even-indexed Lucas numbers.

    These are the phi^2-powered integer moments from the weight-enumerator
    transfer matrix. Equals A005248 (Lucas bisection); the quantum
    interpretation as trace(T*^k) is new.
    """
    return lucas(2 * k)

# ════════════════════════════════════════════════════════════════════════════════
# UTILITIES
# ════════════════════════════════════════════════════════════════════════════════

def generate_all_sequences(count: int = 20) -> Dict[str, List[int]]:
    """Generate all 9 Kaleidoscope sequences."""
    return {
        'A393329': [seq1_cycle_lb_numerator(n) for n in range(count)],
        'A394248': [seq2_mersenne_numerator(n) for n in range(count)],
        'A394249': [seq3_mersenne_gcd(n) for n in range(count)],
        'lucas_num': [seq4_lucas_numerator(n) for n in range(count)],
        'lucas_gcd': [seq5_lucas_gcd(n) for n in range(count)],
        'ml_interference': [seq6_mersenne_lucas_gcd(n) for n in range(1, count + 1)],
        'binary_preservation': [seq7_binary_preservation(n) for n in range(count)],
        'cross_gcd': [seq8_cross_gcd(n) for n in range(count)],
        'A005248': [seq9_weight_moments(k) for k in range(count)],
    }

def verify_pairings(count: int = 20) -> bool:
    """Verify numerator x GCD = base value for both families."""
    for n in range(count):
        # Mersenne: seq2 x seq3 = 2^{n+2} - 1
        if seq2_mersenne_numerator(n) * seq3_mersenne_gcd(n) != mersenne(n + 2):
            return False
        # Lucas: seq4 x seq5 = L_{n+1}
        if seq4_lucas_numerator(n) * seq5_lucas_gcd(n) != lucas(n + 1):
            return False
    return True

def find_seq8_spikes(limit: int = 100) -> List[tuple]:
    """Find all spikes (values > 1) in seq8. All spike values are prime."""
    return [(n, seq8_cross_gcd(n)) for n in range(limit) if seq8_cross_gcd(n) > 1]
