|
1 |
| -### PROBLEM ### |
2 |
| -""" |
3 |
| -We are given a rod of length n and we are given the array of prices, also of |
4 |
| -length n. This array contains the price for selling a rod at a certain length. |
5 |
| -For example, prices[5] shows the price we can sell a rod of length 5. |
6 |
| -Generalising, prices[x] shows the price a rod of length x can be sold. |
7 |
| -We are tasked to find the optimal solution to sell the given rod. |
8 |
| -""" |
9 |
| - |
10 |
| -### SOLUTION ### |
11 |
| -""" |
12 |
| -Profit(n) = max(1<i<n){Price(n),Price(i)+Profit(n-i)} |
13 |
| -
|
14 |
| -When we receive a rod, we have two options: |
15 |
| -a) Don't cut it and sell it as is (receiving prices[length]) |
16 |
| -b) Cut it and sell it in two parts. The length we cut it and the rod we are |
17 |
| -left with, which we have to try and sell separately in an efficient way. |
18 |
| -Choose the maximum price we can get. |
19 |
| -""" |
20 |
| - |
21 |
| -def CutRod(n): |
22 |
| - if(n == 1): |
23 |
| - #Cannot cut rod any further |
24 |
| - return prices[1] |
25 |
| - |
26 |
| - noCut = prices[n] #The price you get when you don't cut the rod |
27 |
| - yesCut = [-1 for x in range(n)] #The prices for the different cutting options |
28 |
| - |
29 |
| - for i in range(1,n): |
30 |
| - if(solutions[i] == -1): |
31 |
| - #We haven't calulated solution for length i yet. |
32 |
| - #We know we sell the part of length i so we get prices[i]. |
33 |
| - #We just need to know how to sell rod of length n-i |
34 |
| - yesCut[i] = prices[i] + CutRod(n-i) |
35 |
| - else: |
36 |
| - #We have calculated solution for length i. |
37 |
| - #We add the two prices. |
38 |
| - yesCut[i] = prices[i] + solutions[n-i] |
39 |
| - |
40 |
| - #We need to find the highest price in order to sell more efficiently. |
41 |
| - #We have to choose between noCut and the prices in yesCut. |
42 |
| - m = noCut #Initialize max to noCut |
43 |
| - for i in range(n): |
44 |
| - if(yesCut[i] > m): |
45 |
| - m = yesCut[i] |
46 |
| - |
47 |
| - solutions[n] = m |
48 |
| - return m |
49 |
| - |
50 |
| - |
51 |
| - |
52 |
| -### EXAMPLE ### |
53 |
| -length = 5 |
54 |
| -#The first price, 0, is for when we have no rod. |
55 |
| -prices = [0, 1, 3, 7, 9, 11, 13, 17, 21, 21, 30] |
56 |
| -solutions = [-1 for x in range(length+1)] |
57 |
| - |
58 |
| -print(CutRod(length)) |
| 1 | +from typing import List |
| 2 | + |
| 3 | +def rod_cutting(prices: List[int],length: int) -> int: |
| 4 | + """ |
| 5 | + Given a rod of length n and array of prices that indicate price at each length. |
| 6 | + Determine the maximum value obtainable by cutting up the rod and selling the pieces |
| 7 | + |
| 8 | + >>> rod_cutting([1,5,8,9],4) |
| 9 | + 10 |
| 10 | + >>> rod_cutting([1,1,1],3) |
| 11 | + 3 |
| 12 | + >>> rod_cutting([1,2,3], -1) |
| 13 | + Traceback (most recent call last): |
| 14 | + ValueError: Given integer must be greater than 1, not -1 |
| 15 | + >>> rod_cutting([1,2,3], 3.2) |
| 16 | + Traceback (most recent call last): |
| 17 | + TypeError: Must be int, not float |
| 18 | + >>> rod_cutting([], 3) |
| 19 | + Traceback (most recent call last): |
| 20 | + AssertionError: prices list is shorted than length: 3 |
| 21 | + |
| 22 | + |
| 23 | +
|
| 24 | + Args: |
| 25 | + prices: list indicating price at each length, where prices[0] = 0 indicating rod of zero length has no value |
| 26 | + length: length of rod |
| 27 | +
|
| 28 | + Returns: |
| 29 | + Maximum revenue attainable by cutting up the rod in any way. |
| 30 | + """ |
| 31 | + |
| 32 | + prices.insert(0, 0) |
| 33 | + if not isinstance(length, int): |
| 34 | + raise TypeError('Must be int, not {0}'.format(type(length).__name__)) |
| 35 | + if length < 0: |
| 36 | + raise ValueError('Given integer must be greater than 1, not {0}'.format(length)) |
| 37 | + assert len(prices) - 1 >= length, "prices list is shorted than length: {0}".format(length) |
| 38 | + |
| 39 | + return rod_cutting_recursive(prices, length) |
| 40 | + |
| 41 | +def rod_cutting_recursive(prices: List[int],length: int) -> int: |
| 42 | + #base case |
| 43 | + if length == 0: |
| 44 | + return 0 |
| 45 | + value = float('-inf') |
| 46 | + for firstCutLocation in range(1,length+1): |
| 47 | + value = max(value, prices[firstCutLocation]+rod_cutting_recursive(prices,length - firstCutLocation)) |
| 48 | + return value |
| 49 | + |
| 50 | + |
| 51 | +def main(): |
| 52 | + assert rod_cutting([1,5,8,9,10,17,17,20,24,30],10) == 30 |
| 53 | + # print(rod_cutting([],0)) |
| 54 | + |
| 55 | +if __name__ == '__main__': |
| 56 | + main() |
| 57 | + |
0 commit comments