From 52c4305d9ef08401ad3268ea189ec66f3a46df98 Mon Sep 17 00:00:00 2001 From: Sanders Lin <45224617+SandersLin@users.noreply.github.com> Date: Thu, 11 Jul 2019 01:13:58 +0800 Subject: [PATCH 1/4] Update rod_cutting.py A hopefully clearer implementation without dependence on global variables. --- dynamic_programming/rod_cutting.py | 67 +++++++++++------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/dynamic_programming/rod_cutting.py b/dynamic_programming/rod_cutting.py index 34350cb8202b..a2c074c31866 100644 --- a/dynamic_programming/rod_cutting.py +++ b/dynamic_programming/rod_cutting.py @@ -1,16 +1,6 @@ -### PROBLEM ### -""" -We are given a rod of length n and we are given the array of prices, also of -length n. This array contains the price for selling a rod at a certain length. -For example, prices[5] shows the price we can sell a rod of length 5. -Generalising, prices[x] shows the price a rod of length x can be sold. -We are tasked to find the optimal solution to sell the given rod. -""" - ### SOLUTION ### """ -Profit(n) = max(1 m): - m = yesCut[i] + Returns: + Maximum revenue attainable by cutting up the rod in any way. - solutions[n] = m - return m + Raises: + KeyError: Raises an exception. + """ + #base case + if length == 0: + return 0 + value = float('-inf') + for firstCutLocation in range(1,length+1): + value = max(value, prices[firstCutLocation]+rod_cutting_recursive(prices,length - firstCutLocation)) + return value +def main(): + assert rod_cutting_recursive([0,1,5,8,9,10,17,17,20,24,30],10) == 30 + +if __name__ == '__main__': + main() -### EXAMPLE ### -length = 5 -#The first price, 0, is for when we have no rod. -prices = [0, 1, 3, 7, 9, 11, 13, 17, 21, 21, 30] -solutions = [-1 for x in range(length+1)] -print(CutRod(length)) From a6f07ab08cbacdc304dd323a68042e459a1c0e92 Mon Sep 17 00:00:00 2001 From: Sanders Lin <45224617+SandersLin@users.noreply.github.com> Date: Thu, 11 Jul 2019 01:45:30 +0800 Subject: [PATCH 2/4] Update rod_cutting.py added doctests --- dynamic_programming/rod_cutting.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/dynamic_programming/rod_cutting.py b/dynamic_programming/rod_cutting.py index a2c074c31866..941bf283e009 100644 --- a/dynamic_programming/rod_cutting.py +++ b/dynamic_programming/rod_cutting.py @@ -1,27 +1,19 @@ -### SOLUTION ### -""" -Optimal Substructure: -When we receive a rod, we have two options: -a) Don't cut it and sell it as is (receiving prices[length]) -b) Cut it and sell it in two parts. The length we cut it and the rod we are -left with, which we have to try and sell separately in an efficient way. -Choose the maximum price we can get. -""" def rod_cutting_recursive(prices,length): """ Given a rod of length n and array of prices that indicate price at each length. Determine the maximum value obtainable by cutting up the rod and selling the pieces - + >>> rod_cutting_recursive([0,1,5,8,9],4) + 10 + >>> rod_cutting_recursive([0,1,1,1],3) + 3 + Args: - prices: list indicating price at each length, where prices[0] = 0 indicating rod of zero length has no value + prices: list indicating price at each length, where prices[0] = 0 indicating rod of zero length has no value length: length of rod - + Returns: Maximum revenue attainable by cutting up the rod in any way. - - Raises: - KeyError: Raises an exception. """ #base case if length == 0: @@ -34,7 +26,7 @@ def rod_cutting_recursive(prices,length): def main(): assert rod_cutting_recursive([0,1,5,8,9,10,17,17,20,24,30],10) == 30 - + if __name__ == '__main__': main() From de1b7614a16a30077357733b56cdcee3ea5200ae Mon Sep 17 00:00:00 2001 From: Sanders Lin <45224617+SandersLin@users.noreply.github.com> Date: Thu, 11 Jul 2019 03:02:33 +0800 Subject: [PATCH 3/4] Update rod_cutting.py --- dynamic_programming/rod_cutting.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dynamic_programming/rod_cutting.py b/dynamic_programming/rod_cutting.py index 941bf283e009..72db355512de 100644 --- a/dynamic_programming/rod_cutting.py +++ b/dynamic_programming/rod_cutting.py @@ -3,10 +3,6 @@ def rod_cutting_recursive(prices,length): """ Given a rod of length n and array of prices that indicate price at each length. Determine the maximum value obtainable by cutting up the rod and selling the pieces - >>> rod_cutting_recursive([0,1,5,8,9],4) - 10 - >>> rod_cutting_recursive([0,1,1,1],3) - 3 Args: prices: list indicating price at each length, where prices[0] = 0 indicating rod of zero length has no value @@ -14,6 +10,11 @@ def rod_cutting_recursive(prices,length): Returns: Maximum revenue attainable by cutting up the rod in any way. + + >>> rod_cutting_recursive([0,1,5,8,9],4) + 10 + >>> rod_cutting_recursive([0,1,1,1],3) + 3 """ #base case if length == 0: From 57187bcd9739e98ec0cac08e9d0325350b12830a Mon Sep 17 00:00:00 2001 From: Sanders Lin <45224617+SandersLin@users.noreply.github.com> Date: Thu, 11 Jul 2019 11:55:16 +0800 Subject: [PATCH 4/4] Update rod_cutting.py --- dynamic_programming/rod_cutting.py | 43 +++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/dynamic_programming/rod_cutting.py b/dynamic_programming/rod_cutting.py index 72db355512de..c3111dcfc8a1 100644 --- a/dynamic_programming/rod_cutting.py +++ b/dynamic_programming/rod_cutting.py @@ -1,21 +1,44 @@ +from typing import List -def rod_cutting_recursive(prices,length): +def rod_cutting(prices: List[int],length: int) -> int: """ Given a rod of length n and array of prices that indicate price at each length. Determine the maximum value obtainable by cutting up the rod and selling the pieces + >>> rod_cutting([1,5,8,9],4) + 10 + >>> rod_cutting([1,1,1],3) + 3 + >>> rod_cutting([1,2,3], -1) + Traceback (most recent call last): + ValueError: Given integer must be greater than 1, not -1 + >>> rod_cutting([1,2,3], 3.2) + Traceback (most recent call last): + TypeError: Must be int, not float + >>> rod_cutting([], 3) + Traceback (most recent call last): + AssertionError: prices list is shorted than length: 3 + + + Args: - prices: list indicating price at each length, where prices[0] = 0 indicating rod of zero length has no value + prices: list indicating price at each length, where prices[0] = 0 indicating rod of zero length has no value length: length of rod - + Returns: Maximum revenue attainable by cutting up the rod in any way. - - >>> rod_cutting_recursive([0,1,5,8,9],4) - 10 - >>> rod_cutting_recursive([0,1,1,1],3) - 3 """ + + prices.insert(0, 0) + if not isinstance(length, int): + raise TypeError('Must be int, not {0}'.format(type(length).__name__)) + if length < 0: + raise ValueError('Given integer must be greater than 1, not {0}'.format(length)) + assert len(prices) - 1 >= length, "prices list is shorted than length: {0}".format(length) + + return rod_cutting_recursive(prices, length) + +def rod_cutting_recursive(prices: List[int],length: int) -> int: #base case if length == 0: return 0 @@ -26,9 +49,9 @@ def rod_cutting_recursive(prices,length): def main(): - assert rod_cutting_recursive([0,1,5,8,9,10,17,17,20,24,30],10) == 30 + assert rod_cutting([1,5,8,9,10,17,17,20,24,30],10) == 30 + # print(rod_cutting([],0)) if __name__ == '__main__': main() -