diff --git a/eating_cookies/eating_cookies.py b/eating_cookies/eating_cookies.py index 62655d803..f79e9c0a8 100644 --- a/eating_cookies/eating_cookies.py +++ b/eating_cookies/eating_cookies.py @@ -5,8 +5,67 @@ # The cache parameter is here for if you want to implement # a solution that is more efficient than the naive # recursive solution +# cache is the inventory --> 4 cookies +# n is for cookies + def eating_cookies(n, cache=None): - pass + # starter + # base: + if not cache: + cache = [0]*(n+1) + if n < 0: + return 0 + elif n == 0: + return 1 + elif cache[n] > 1: + return cache[n] + else: + cache[n] = eating_cookies(n-1, cache) + eating_cookies(n-2, cache) + eating_cookies(n-3, cache) + return cache[n] + +def eating_cookies2(n, cache=None): + # starter + # base: + + if n <= 0: + return 0 + if n == 1: + return 1 + if n == 2: + return 2 + if n == 3: + return 4 + + return eating_cookies2(n-1) + eating_cookies2(n-2) + eating_cookies2(n-3) +# lines 41 and 42 debug eating cookies2 and it works on small numbers +n=3 +print(eating_cookies2(n-1) + eating_cookies2(n-2) + eating_cookies2(n-3)) + +def eating_cookies3(n, cache=None): + # starter + if cache is None: + cache = {} + # base: + + if n <= 0: + return 0 + elif n == 1: + return 1 + elif n == 2: + return 2 + elif n == 3: + return 4 + elif cache and cache[n]: + return cache[n] + else: + cache[n] = eating_cookies3(n-1, cache) + eating_cookies3(n-2, cache) + eating_cookies3(n-3, cache) + + + return cache[n] +y = eating_cookies3(400, {}) +print(y) + + if __name__ == "__main__": if len(sys.argv) > 1: diff --git a/eating_cookies/improving.py b/eating_cookies/improving.py new file mode 100644 index 000000000..6e566e69e --- /dev/null +++ b/eating_cookies/improving.py @@ -0,0 +1,37 @@ + +cache = {0: 1, 1: 1} +def recursion_fibonacci(n): + #base + # if n == 0: + # return 0 + # if n == 1: + # return 1 + + # handling cache + if n in cache: + return cache[n] + # if not in cache: + cache[n] = recursion_fibonacci(n-1) + recursion_fibonacci(n-2) + return cache[n] + +x=recursion_fibonacci(10) +print(x) +# this log n which is reverse of exponential: +nums = [1,2,3,4,5,6,7,8,9] +def bin_search(arr, val): + l = 0 + m = len(arr)//2 + r = len(arr) - 1 + while l < r: + if arr[m] == val: + return True + elif val < arr[m]: + # move left + return m -1 + else: + # move right + return m + 1 + return False + +y = bin_search(nums, 5) +print(y) diff --git a/knapsack/knapsack.py b/knapsack/knapsack.py index a130284f1..ec28a12fa 100644 --- a/knapsack/knapsack.py +++ b/knapsack/knapsack.py @@ -5,9 +5,60 @@ Item = namedtuple('Item', ['index', 'size', 'value']) -def knapsack_solver(items, capacity): - pass - +def knapsack_solver(capacity, items): + # "running capacities" from 0 up to and including the maximum weight W. + bestvalues = [[0] * (items + 1) + for i in range(len(capacity) + 1)] + + # Enumerate through the items and fill in the best-value table + for i, (value, weight) in enumerate(capacity): + # Increment i, because the first row (0) is the case where no items + # are chosen, and is already initialized as 0, so we're skipping it + i += 1 + for j in range(items + 1): + # Handle the case where the weight of the current item is greater + # than the "running capacity" - we can't add it to the knapsack + if weight > j: + bestvalues[i][items] = bestvalues[i - 1][items] + else: + # Otherwise, we must choose between two possible candidate values: + # 1) the value of "running capacity" as it stands with the last item + # that was computed; if this is larger, then we skip the current item + # 2) the value of the current item plus the value of a previously computed + # set of items, constrained by the amount of capacity that would be left + # in the knapsack (running capacity - item's weight) + candidate1 = bestvalues[i - 1][j] + candidate2 = bestvalues[i - 1][j - weight] + value + + # Just take the maximum of the two candidates; by doing this, we are + # in effect "setting in stone" the best value so far for a particular + # prefix of the items, and for a particular "prefix" of knapsack capacities + bestvalues[i][j] = max(candidate1, candidate2) + + # Reconstruction + # Iterate through the values table, and check + # to see which of the two candidates were chosen. We can do this by simply + # checking if the value is the same as the value of the previous row. If so, then + # we say that the item was not included in the knapsack (this is how we arbitrarily + # break ties) and simply move the pointer to the previous row. Otherwise, we add + # the item to the reconstruction list and subtract the item's weight from the + # remaining capacity of the knapsack. Once we reach row 0, we're done + reconstruction = [] + i = len(capacity) + z = items + while i > 0: + if bestvalues[i][z] != bestvalues[i - 1][z]: + reconstruction.append(items[i - 1]) + z -= items[i - 1][1] + i -= 1 + + # Reverse the reconstruction list, so that it is presented + # in the order that it was given + reconstruction.reverse() + + # Return the best value, and the reconstruction list + return bestvalues[len(capacity)][items], reconstruction + if __name__ == '__main__': if len(sys.argv) > 1: diff --git a/making_change/making_change.py b/making_change/making_change.py index 9adad4470..a7730a185 100644 --- a/making_change/making_change.py +++ b/making_change/making_change.py @@ -3,7 +3,14 @@ import sys def making_change(amount, denominations): - pass + cache = [0 for i in range(amount + 1)] + cache[0] = 1 + + for d in denominations: + for amount in range(d, amount +1): + cache[amount] = cache[amount] + cache[amount - d] + + return cache[amount] if __name__ == "__main__": diff --git a/recipe_batches/recipe_batches.py b/recipe_batches/recipe_batches.py index c845950c5..8f081c12f 100644 --- a/recipe_batches/recipe_batches.py +++ b/recipe_batches/recipe_batches.py @@ -3,7 +3,15 @@ import math def recipe_batches(recipe, ingredients): - pass + # start + new_ingredients_for_item = [0]*len(recipe) + counter = 0 + #base + for i in recipe: + if i in ingredients: + new_ingredients_for_item[counter] = int(ingredients[i]/recipe[i]) + counter += 1 + return min(new_ingredients_for_item) if __name__ == '__main__': diff --git a/rock_paper_scissors/rps.py b/rock_paper_scissors/rps.py index 0fc53356e..eaa27a07f 100644 --- a/rock_paper_scissors/rps.py +++ b/rock_paper_scissors/rps.py @@ -3,8 +3,20 @@ import sys def rock_paper_scissors(n): - pass + #start + choices = ['rock', 'paper', 'scissors'] + possible_plays = [] + #base + def rps_helper_fun(result, num_plays): + # this should stop the recursion if there are no plays + if num_plays == 0: + possible_plays.append(result) + return + for i in range(0, len(choices)): + rps_helper_fun(result + [choices[i]], num_plays -1) + rps_helper_fun([], n) + return possible_plays if __name__ == "__main__": if len(sys.argv) > 1: diff --git a/stock_prices/stock_prices.py b/stock_prices/stock_prices.py index 9de20bc94..d5dd19021 100644 --- a/stock_prices/stock_prices.py +++ b/stock_prices/stock_prices.py @@ -3,9 +3,18 @@ import argparse def find_max_profit(prices): - pass + current_min_price = prices[0] + max_profit = prices[1] - current_min_price + for i in range(len(prices)): + for j in range(i + 1, len(prices)): + if prices[j] - prices[i] > max_profit: + max_profit = prices[j] - prices[i] + return max_profit + + + if __name__ == '__main__': # This is just some code to accept inputs from the command line parser = argparse.ArgumentParser(description='Find max profit from prices.')