# fibonacci variants

def fibonacci(n: int) -> int:
    """nth fibonacci number, where fibonacci(0) is 0 and fibonacci(1) is 1,
    and fibonacci(n) = fibonacci(n-1) + fibonacci(n-2) if n > 1

    >>> fibonacci(5)
    5
    >>> fibonacci(6)
    8
    """
    return n if n < 2 else fibonacci(n - 1) + fibonacci(n - 2)







def fibonacci_mem(n: int) -> int:
    """memoized fibonacci"""
    cached = {}
    def fib_rec(n: int) -> int:
        if not n in cached:
            if n < 2:
                cached[n] = n
            else:
                cached[n] = fib_rec(n - 1) + fib_rec(n - 2)
        return cached[n]
    return fib_rec(n)


def memoize(f: 'function') -> 'function':
    """Return memoized version of f"""
    table = {}
    def g(x):
        if not x in table:
            table[x] = f(x)
        else:
            pass
        return table[x]
    return g








import random
from sys import setrecursionlimit
#setrecursionlimit(10000)
L = list(range(1000))
#random.shuffle(L)
def quick(L: list) -> list:
    """Produce list with same elements as L in ascending order"""
    return (quick([x for x in L[1:] if x < L[0]]) +
            [L[0]] +
            quick([x for x in L[1:] if x >= L[0]])) if len(L) > 1 else L














def quick2(L: list) -> list:
    """Produce list with same elements as L in ascending order"""
    if len(L) < 2:
        return L
    else:
        p = random.randint(0, len(L) - 1)
        return (quick2([x for x in L[:p] + L[p+1:] if x < L[p]]) +
                [L[p]] + quick2([x for x in L[:p] + L[p+1:] if x >= L[p]]))

