#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon May  4 10:15:36 2026

@author: pjoulaud
"""
from functools import lru_cache, wraps
from time import perf_counter_ns as now

def chrono2(f):
    @wraps(f)
    def my_f(*args, **kwargs):
        t0 = now()
        v = f(*args, **kwargs)
        t1 = now()
        print(t1-t0, "nanosecondes")
        return v
    return my_f


def memoise(f):
    dico = {}
    @wraps(f)
    def my_f(*args, **kwargs):
        if args not in dico :
            res = f(*args, **kwargs)
            dico[args] = res
        return dico[args]
    return my_f

def fibo_rec(n:int)->int :
    if n==0 :
        return 0
    elif n==1:
        return 1
    else :
        return fibo_rec(n-2)+fibo_rec(n-1)

@memoise
def fibo_memo(n:int)->int :
    if n==0 :
        return 0
    elif n==1:
        return 1
    else :
        return fibo_memo(n-2)+fibo_memo(n-1)

@lru_cache(maxsize=None)
def fibo_lru(n:int)->int :
    if n==0 :
        return 0
    elif n==1:
        return 1
    else :
        return fibo_lru(n-2)+fibo_lru(n-1)
    
def fibo_iter(n:int)->int :    
    u0, u1 = 0, 1
    for i in range(n-1):
        u2 = u1 + u0
        u1, u0 = u2, u1
    if n==0 :
        return u0
    elif n==1:
        return u1
    else :
        return u2

def fibo_dico(n:int)->int :
    dico = {0:0, 1:1}
    def t(n:int)->int :
        if n not in dico :
            dico[n] = t(n-2)+t(n-1)
        return dico[n]    
    return t(n)

import matplotlib.pyplot as plt
import timeit

# Données : les nombres de 1 à 10
x = list(range(0, 30, 5))


rec, memo, lru, itera, dictio = [], [], [], [], []
for un_x in x :
    rec.append(timeit.timeit('fibo_rec(un_x)', number=100, globals=globals()))
    memo.append(timeit.timeit('fibo_memo(un_x)', number=100, globals=globals()))
    lru.append(timeit.timeit('fibo_lru(un_x)', number=100, globals=globals()))
    itera.append(timeit.timeit('fibo_iter(un_x)', number=100, globals=globals()))
    dictio.append(timeit.timeit('fibo_dico(un_x)', number=100, globals=globals()))

plt.axis([x[0], x[-1], 0, 7e-4])

# Créer un graphique
plt.plot(x, memo, marker='o', linestyle='-', color='b', label="memo")
plt.plot(x, lru, marker='x', linestyle='-.', color='r', label="lru")
plt.plot(x, itera, marker='o', linestyle='-', color='g', label="itera")
plt.plot(x, dictio, marker='x', linestyle='-.', color='m', label="dictio")
plt.plot(x, rec, marker='o', linestyle='-.', color='k', label="rec")

# Ajouter des étiquettes et un titre
plt.xlabel("Nombres")
plt.ylabel("Fonctions")
plt.title("Différentes fonctions Fibonacci")

# Afficher la légende
plt.legend()

# Afficher la grille
plt.grid(True)

# Afficher le graphique
plt.show()


