11from typing import List
22
3+ # Cache dictionary to store computed results
4+ # Key: (total, tuple(coins)) -> Value: number of ways
5+ change_cache = {}
36
47def ways_to_make_change (total : int ) -> int :
58 """
69 Given access to coins with the values 1, 2, 5, 10, 20, 50, 100, 200, returns a count of all of the ways to make the passed total value.
710
811 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.
912 """
10- return ways_to_make_change_helper (total , [200 , 100 , 50 , 20 , 10 , 5 , 2 , 1 ])
13+ # Clear cache for each new call to avoid interference between tests
14+ change_cache .clear ()
15+ coins = [200 , 100 , 50 , 20 , 10 , 5 , 2 , 1 ]
16+ return ways_to_make_change_helper (total , coins )
1117
1218
1319def ways_to_make_change_helper (total : int , coins : List [int ]) -> int :
1420 """
1521 Helper function for ways_to_make_change to avoid exposing the coins parameter to callers.
1622 """
17- if total == 0 or len (coins ) == 0 :
18- return 0
23+ # Create a cache key - use tuple of coins since lists are not hashable
24+ cache_key = (total , tuple (coins ))
25+
26+ # Check if we already computed this combination
27+ if cache_key in change_cache :
28+ return change_cache [cache_key ]
29+
30+ # Base cases
31+ if total == 0 :
32+ return 1 # One way to make 0: use no coins
33+ if len (coins ) == 0 :
34+ return 0 # No coins left but still need to make total > 0
1935
2036 ways = 0
2137 for coin_index in range (len (coins )):
@@ -29,4 +45,7 @@ def ways_to_make_change_helper(total: int, coins: List[int]) -> int:
2945 intermediate = ways_to_make_change_helper (total - total_from_coins , coins = coins [coin_index + 1 :])
3046 ways += intermediate
3147 count_of_coin += 1
32- return ways
48+
49+ # Store result in cache before returning
50+ change_cache [cache_key ] = ways
51+ return ways
0 commit comments