From fa68aa61094a4cbf4d16dd7194ce482e06679275 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Tue, 21 Dec 2021 10:08:18 +0100 Subject: [PATCH] caching for when functools.cache() is not available (looking at you, pypy!) --- tools/int_seq.py | 13 ++++--------- tools/tools.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/tools/int_seq.py b/tools/int_seq.py index 83c7425..ee701a7 100644 --- a/tools/int_seq.py +++ b/tools/int_seq.py @@ -1,5 +1,5 @@ import math -from typing import Dict +from .tools import cache def factorial(n: int) -> int: @@ -10,7 +10,8 @@ def factorial(n: int) -> int: return math.factorial(n) -def fibonacci(n: int, cache: Dict[int, int] = None) -> int: +@cache +def fibonacci(n: int) -> int: """ F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1 0, 1, 1, 2, 3, 5, 8, 13, 21, ... @@ -18,13 +19,7 @@ def fibonacci(n: int, cache: Dict[int, int] = None) -> int: if n < 2: return n - if cache is None: - cache = {} - - if n not in cache: - cache[n] = fibonacci(n - 1, cache) + fibonacci(n - 2, cache) - - return cache[n] + return fibonacci(n - 1) + fibonacci(n - 2) def triangular(n: int) -> int: diff --git a/tools/tools.py b/tools/tools.py index 69e9b0e..0266884 100644 --- a/tools/tools.py +++ b/tools/tools.py @@ -2,6 +2,7 @@ import datetime import inspect import os.path import sys +from functools import wraps from typing import Any @@ -42,3 +43,18 @@ def human_readable_time_from_delta(delta: datetime.timedelta) -> str: time_str += "00:" return time_str + "%02d" % (delta.seconds % 60) + + +def cache(func): + saved = {} + + @wraps(func) + def newfunc(*args): + if args in saved: + return saved[args] + + result = func(*args) + saved[args] = result + return result + + return newfunc