#!/usr/bin/env python3
"""
Scenario 2: Memoization with functools.lru_cache
================================================
Adding @lru_cache transforms O(2^n) into O(n) by caching results.

EXERCISES:
1. Run: time python3 fib_cached.py 35
2. Compare to fib_slow.py - how much faster?
3. Profile: python3 -m cProfile -s ncalls fib_cached.py 35
4. Notice the dramatic reduction in call count
5. Try a much larger number: python3 fib_cached.py 100
"""

import sys
from functools import lru_cache


@lru_cache(maxsize=None)  # Unlimited cache size
def fib(n):
    """Compute the nth Fibonacci number with memoization."""
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)


def main():
    n = 35
    if len(sys.argv) > 1:
        n = int(sys.argv[1])
    
    print(f"Computing fib({n}) with memoization...")
    result = fib(n)
    print(f"fib({n}) = {result}")
    
    # Show cache statistics
    print(f"\nCache info: {fib.cache_info()}")


if __name__ == "__main__":
    main()
