diff --git a/eating_cookies/eating_cookies.py b/eating_cookies/eating_cookies.py index 62655d803..17e989a50 100644 --- a/eating_cookies/eating_cookies.py +++ b/eating_cookies/eating_cookies.py @@ -1,12 +1,42 @@ #!/usr/bin/python import sys +# from numpy import roots, flip # The cache parameter is here for if you want to implement # a solution that is more efficient than the naive # recursive solution -def eating_cookies(n, cache=None): - pass +def eating_cookies(n, cache = None): + # Note: this program should work fine, in theory, but Numpy's implementation of root + # finding builds up floating-point errors too fast. It gives the wrong answer for 0, + # and it reliably gives almost, but not quite, correct answers on large values. + # int(round(sum(roots([1, -1, -1, -1]) ** (n + 2) * flip(roots([44, 0, 4, -1]))))) + + # this function passes all tests when implemented in Mathematica, however + # eatingCookies[n_] := + # Round[Inner[Times, + # Array[Root[-1 - # - #^2 + #^3 &, #] &, 3]^(n + 2), + # Array[Root[-1 + 4*# + 44*#^3 &, #] &, 3], Plus]] + # So, clearly, the concept is fine, but Python's libraries aren't. + + if n < 2: + return 1 + elif n == 2: + return 2 + + if cache == None: + cache = [None] * (n + 1) + else: + cache = cache + + if cache[n] == None or cache[n] == 0: + cache[n - 3] = eating_cookies(n - 3, cache) + cache[n - 2] = eating_cookies(n - 2, cache) + cache[n - 1] = eating_cookies(n - 1, cache) + + return cache[n - 1] + cache[n - 2] + cache[n - 3] + else: + return cache[n] if __name__ == "__main__": if len(sys.argv) > 1: diff --git a/making_change/making_change.py b/making_change/making_change.py index 9adad4470..e573a8918 100644 --- a/making_change/making_change.py +++ b/making_change/making_change.py @@ -1,10 +1,33 @@ #!/usr/bin/python import sys +from math import ceil -def making_change(amount, denominations): - pass +def remains(amount, denom): + return [ amount - i * denom for i in range(amount // denom + 1) ] +def making_change(amount, denominations, caches = None): + """ Note: this assumes the denominations are pre-sorted. + + This is also not very efficient. + If an expression for an explicit formula can be worked out, + it could be made very, very fast; but I don't think + numpy can maintain the accuracy for accurate answers. + """ + + if len(denominations) == 2: + return amount // denominations[1] + 1 + + if caches == None: + caches = { i: [None] * (amount + 1) for i in denominations } + + if caches[denominations[-1]][amount] == None: + caches[denominations[-1]][amount] =\ + sum([ making_change(a, denominations[:-1]) + for a in remains(amount, denominations[-1]) ]) + return caches[denominations[-1]][amount] + else: + return caches[denominations[-1]][amount] if __name__ == "__main__": # Test our your implementation from the command line diff --git a/recipe_batches/recipe_batches.py b/recipe_batches/recipe_batches.py index c845950c5..f21f250a8 100644 --- a/recipe_batches/recipe_batches.py +++ b/recipe_batches/recipe_batches.py @@ -3,7 +3,8 @@ import math def recipe_batches(recipe, ingredients): - pass + return min([ ingredients.get(k, 0) // recipe[k] for k in recipe.keys() ]) + if __name__ == '__main__': diff --git a/rock_paper_scissors/rps.py b/rock_paper_scissors/rps.py index 0fc53356e..b8cdde9f8 100644 --- a/rock_paper_scissors/rps.py +++ b/rock_paper_scissors/rps.py @@ -2,9 +2,29 @@ import sys +def number_to_base(num, base, padding = 1): + """Change ''num'' to a given numerical base + + The return value will be left-padded until it's length is ''padding''. + """ + + digit_list = [] + currentnum = num + while currentnum: + mod = currentnum % base + currentnum = currentnum // base + digit_list = [mod] + digit_list + while len(digit_list) < padding: + digit_list = [0] + digit_list + return digit_list + def rock_paper_scissors(n): - pass + """ Enumerate all numbers from 0 to 3 ** n in base three, and map + 0 to 'rock', 1 to 'paper', and 2 to 'scissors'. + """ + rps = ["rock", "paper", "scissors"] + return [ [ rps[d] for d in number_to_base(i, 3, n) ] for i in range(3 ** n) ] if __name__ == "__main__": if len(sys.argv) > 1: diff --git a/stock_prices/stock_prices.py b/stock_prices/stock_prices.py index 9de20bc94..273cc7c48 100644 --- a/stock_prices/stock_prices.py +++ b/stock_prices/stock_prices.py @@ -3,7 +3,7 @@ import argparse def find_max_profit(prices): - pass + return max([ max(prices[i+1:]) - p for i, p in enumerate(prices[:-1]) ]) if __name__ == '__main__':