Decorador de cache
Em código real, funções recursivas como cálculo de Fibonacci, processamento de grafos ou consultas a APIs podem repetir os mesmos cálculos milhares de vezes, desperdiçando tempo. A memoização guarda resultados já computados e os reutiliza, transformando funções exponenciais em lineares. Um decorador de cache encapsula essa lógica de forma limpa e reutilizável.
O PROBLEMA
Crie decorador @cache para memoizar resultados. Aplique em fibonacci.
EXEMPLO
fibonacci(35) com cache: ~0.001s
SOBRE O CONCEITO
A memoização armazena o retorno de uma função em um dicionário, usando os argumentos como chave. Para isso, cria-se um decorador que envolve a função original: antes de executar, verifica se a chave (gerada a partir de *args) existe no cache; se sim, retorna o valor salvo; senão, calcula, guarda e retorna. O erro comum 'cache não persistindo entre chamadas' acontece quando o dicionário é recriado a cada chamada da função decorada — por exemplo, se o cache for definido dentro do decorador sem um contêiner mutável persistente. Para evitar isso, usa-se um dicionário como argumento padrão mutável (ex.: def decorador(func, cache={})) ou armazena-se o cache em um atributo da função (ex.: func.cache). Dessa forma, o cache é compartilhado entre todas as chamadas, garantindo a aceleração desejada.
RESOLUÇÃO