From 6e1269c990d2dc7b3395f6787ba84974c2a244c4 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Mon, 19 Oct 2026 17:36:42 +0100 Subject: [PATCH 1/5] Implement fobonacci exercise using cache --- Sprint-2/improve_with_caches/fibonacci/fibonacci.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Sprint-2/improve_with_caches/fibonacci/fibonacci.py b/Sprint-2/improve_with_caches/fibonacci/fibonacci.py index 60cc6671..27617629 100644 --- a/Sprint-2/improve_with_caches/fibonacci/fibonacci.py +++ b/Sprint-2/improve_with_caches/fibonacci/fibonacci.py @@ -1,4 +1,13 @@ +cache = { + 0: 0, + 1: 1 +} + def fibonacci(n): + if n in cache: + return cache[n] if n <= 1: return n - return fibonacci(n - 1) + fibonacci(n - 2) + result = fibonacci(n - 1) + fibonacci(n - 2) + cache[n] = result + return result From 81e18941fbf2c309bf210d766c15ccf72ff7211a Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Mon, 19 Oct 2026 22:30:45 +0100 Subject: [PATCH 2/5] Implement making change with cache --- .../making_change/making_change.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Sprint-2/improve_with_caches/making_change/making_change.py b/Sprint-2/improve_with_caches/making_change/making_change.py index 255612e5..c7975dcc 100644 --- a/Sprint-2/improve_with_caches/making_change/making_change.py +++ b/Sprint-2/improve_with_caches/making_change/making_change.py @@ -1,5 +1,5 @@ from typing import List - +cache = {} def ways_to_make_change(total: int) -> int: """ @@ -14,9 +14,17 @@ def ways_to_make_change_helper(total: int, coins: List[int]) -> int: """ Helper function for ways_to_make_change to avoid exposing the coins parameter to callers. """ - if total == 0 or len(coins) == 0: - return 0 + key = (total, tuple(coins)) + if key in cache: + return cache[key] + + if total == 0: + return 1 + + if len(coins) == 0: + return 0 + ways = 0 for coin_index in range(len(coins)): coin = coins[coin_index] @@ -29,4 +37,5 @@ def ways_to_make_change_helper(total: int, coins: List[int]) -> int: intermediate = ways_to_make_change_helper(total - total_from_coins, coins=coins[coin_index+1:]) ways += intermediate count_of_coin += 1 + cache[key] = ways return ways From 4d2360a994385385d37f280e6570e9b88d5972b6 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Tue, 20 Oct 2026 23:26:41 +0100 Subject: [PATCH 3/5] Refactor recursive call. --- .../making_change/making_change.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Sprint-2/improve_with_caches/making_change/making_change.py b/Sprint-2/improve_with_caches/making_change/making_change.py index c7975dcc..ec93c2fe 100644 --- a/Sprint-2/improve_with_caches/making_change/making_change.py +++ b/Sprint-2/improve_with_caches/making_change/making_change.py @@ -1,5 +1,12 @@ from typing import List cache = {} +all_coins = [200, 100, 50, 20, 10, 5, 2, 1] +coin_lists = [all_coins[i:] for i in range(len(all_coins) + 1)] + +coin_list_ids = { + tuple(coins): index + for index, coins in enumerate(coin_lists) +} def ways_to_make_change(total: int) -> int: """ @@ -7,14 +14,14 @@ def ways_to_make_change(total: int) -> int: For instance, there are two ways to make a value of 3: with 3x 1 coins, or with 1x 1 coin and 1x 2 coin. """ - return ways_to_make_change_helper(total, [200, 100, 50, 20, 10, 5, 2, 1]) - + return ways_to_make_change_helper(total, 0) -def ways_to_make_change_helper(total: int, coins: List[int]) -> int: +def ways_to_make_change_helper(total: int, coin_list_id: int) -> int: """ Helper function for ways_to_make_change to avoid exposing the coins parameter to callers. """ - key = (total, tuple(coins)) + coins = coin_lists[coin_list_id] + key = (total, coin_list_id) if key in cache: return cache[key] @@ -34,7 +41,7 @@ def ways_to_make_change_helper(total: int, coins: List[int]) -> int: if total_from_coins == total: ways += 1 else: - intermediate = ways_to_make_change_helper(total - total_from_coins, coins=coins[coin_index+1:]) + intermediate = ways_to_make_change_helper(total - total_from_coins, coin_list_id + coin_index+1) ways += intermediate count_of_coin += 1 cache[key] = ways From 000734d95320ec609bd270eb8a05cf1564eb8d18 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Wed, 21 Oct 2026 15:13:15 +0100 Subject: [PATCH 4/5] Optimize making change with precomputed coin lists and cache key --- .../making_change/making_change.py | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Sprint-2/improve_with_caches/making_change/making_change.py b/Sprint-2/improve_with_caches/making_change/making_change.py index ec93c2fe..363446b4 100644 --- a/Sprint-2/improve_with_caches/making_change/making_change.py +++ b/Sprint-2/improve_with_caches/making_change/making_change.py @@ -1,12 +1,16 @@ from typing import List cache = {} -all_coins = [200, 100, 50, 20, 10, 5, 2, 1] -coin_lists = [all_coins[i:] for i in range(len(all_coins) + 1)] - -coin_list_ids = { - tuple(coins): index - for index, coins in enumerate(coin_lists) -} +coin_lists = [ + [200, 100, 50, 20, 10, 5, 2, 1], # ID 0 + [100, 50, 20, 10, 5, 2, 1], # ID 1 + [50, 20, 10, 5, 2, 1], # ID 2 + [20, 10, 5, 2, 1], # ID 3 + [10, 5, 2, 1], # ID 4 + [5, 2, 1], # ID 5 + [2, 1], # ID 6 + [1], # ID 7 + [] # ID 8 +] def ways_to_make_change(total: int) -> int: """ @@ -41,8 +45,13 @@ def ways_to_make_change_helper(total: int, coin_list_id: int) -> int: if total_from_coins == total: ways += 1 else: - intermediate = ways_to_make_change_helper(total - total_from_coins, coin_list_id + coin_index+1) - ways += intermediate + next_coin_list_id = coin_list_id + coin_index + 1 + intermediate = ways_to_make_change_helper( + total - total_from_coins, + next_coin_list_id + ) + ways += intermediate + count_of_coin += 1 cache[key] = ways return ways From 1ccd8f3fe6b345993ad3d12ac15347bc4c23ae3d Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Wed, 21 Oct 2026 15:28:55 +0100 Subject: [PATCH 5/5] Make change with index-based caching. --- .../making_change/making_change.py | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/Sprint-2/improve_with_caches/making_change/making_change.py b/Sprint-2/improve_with_caches/making_change/making_change.py index 363446b4..7488c933 100644 --- a/Sprint-2/improve_with_caches/making_change/making_change.py +++ b/Sprint-2/improve_with_caches/making_change/making_change.py @@ -1,16 +1,6 @@ from typing import List cache = {} -coin_lists = [ - [200, 100, 50, 20, 10, 5, 2, 1], # ID 0 - [100, 50, 20, 10, 5, 2, 1], # ID 1 - [50, 20, 10, 5, 2, 1], # ID 2 - [20, 10, 5, 2, 1], # ID 3 - [10, 5, 2, 1], # ID 4 - [5, 2, 1], # ID 5 - [2, 1], # ID 6 - [1], # ID 7 - [] # ID 8 -] +all_coins = [200, 100, 50, 20, 10, 5, 2, 1] def ways_to_make_change(total: int) -> int: """ @@ -20,12 +10,11 @@ def ways_to_make_change(total: int) -> int: """ return ways_to_make_change_helper(total, 0) -def ways_to_make_change_helper(total: int, coin_list_id: int) -> int: +def ways_to_make_change_helper(total: int, start_index: int) -> int: """ Helper function for ways_to_make_change to avoid exposing the coins parameter to callers. """ - coins = coin_lists[coin_list_id] - key = (total, coin_list_id) + key = (total, start_index) if key in cache: return cache[key] @@ -33,22 +22,21 @@ def ways_to_make_change_helper(total: int, coin_list_id: int) -> int: if total == 0: return 1 - if len(coins) == 0: + if start_index >= len(all_coins): return 0 ways = 0 - for coin_index in range(len(coins)): - coin = coins[coin_index] + for coin_index in range(start_index, len(all_coins)): + coin = all_coins[coin_index] count_of_coin = 1 while coin * count_of_coin <= total: total_from_coins = coin * count_of_coin if total_from_coins == total: ways += 1 else: - next_coin_list_id = coin_list_id + coin_index + 1 intermediate = ways_to_make_change_helper( total - total_from_coins, - next_coin_list_id + coin_index + 1 ) ways += intermediate