|
| 1 | +""" |
| 2 | +Here Maximum SubArray problem has been implemented on the Share |
| 3 | +Market Data Analysis. Where prices of every day has been given. |
| 4 | +We have to find the buying and selling day so that the profit will |
| 5 | +be maximum. Here the Divide and Conquer method is used and |
| 6 | +time-complexity is O(nlogn).For more information visit- |
| 7 | +<https://en.wikipedia.org/wiki/Maximum_subarray_problem> |
| 8 | +""" |
| 9 | + |
| 10 | + |
| 11 | +def max_sub_array(arr, low, high): |
| 12 | + """ |
| 13 | + Method to find maximum sub array. |
| 14 | +
|
| 15 | + :param low: kjndn |
| 16 | + :param high: kjndknfg |
| 17 | + """ |
| 18 | + if low == high: |
| 19 | + # if there is only one day |
| 20 | + return low, low + 1, arr[low] |
| 21 | + |
| 22 | + else: |
| 23 | + mid = int((low + high) / 2) |
| 24 | + # ll, lh, ls are respectively left-low, left-high, left-sum |
| 25 | + # rl, rh, rs are respectively right-low, right-high, right-sum |
| 26 | + # cl, ch, cs are respectively cross-low, cross-high, cross-sum |
| 27 | + |
| 28 | + ll, lh, ls = max_sub_array(arr, low, mid) |
| 29 | + rl, rh, rs = max_sub_array(arr, mid + 1, high) |
| 30 | + cl, ch, cs = cross_sub_array(arr, low, mid, high) |
| 31 | + |
| 32 | + max_sum = max(ls, rs, cs) |
| 33 | + |
| 34 | + if max_sum is ls: |
| 35 | + return ll, lh, ls |
| 36 | + elif max_sum is rs: |
| 37 | + return rl, rh, rs |
| 38 | + else: |
| 39 | + return cl, ch, cs |
| 40 | + |
| 41 | + |
| 42 | +def cross_sub_array(arr, low, mid, high): |
| 43 | + """ |
| 44 | + :param mid: lsum is left sum |
| 45 | + """ |
| 46 | + lsum = -10000 |
| 47 | + sum = 0 |
| 48 | + maxl = mid |
| 49 | + maxr = mid + 1 |
| 50 | + for i in range(mid, low - 1, -1): |
| 51 | + sum = sum + arr[i] |
| 52 | + if sum > lsum: |
| 53 | + lsum = sum |
| 54 | + maxl = i |
| 55 | + |
| 56 | + # rsum is right sum |
| 57 | + rsum = -10000 |
| 58 | + sum = 0 |
| 59 | + for i in range(mid + 1, high + 1): |
| 60 | + sum = sum + arr[i] |
| 61 | + if sum > rsum: |
| 62 | + rsum = sum |
| 63 | + maxr = i + 1 |
| 64 | + return maxl, maxr, (lsum + rsum) |
| 65 | + |
| 66 | + |
| 67 | +def main(): |
| 68 | + # price is array of the prices where each index of array |
| 69 | + # represents the day. |
| 70 | + # price_difference is array of profit(either +ve or -ve) |
| 71 | + |
| 72 | + price = [4, 9, 5, 13, 16, 7, 8] |
| 73 | + |
| 74 | + if len(price) <= 1: |
| 75 | + print('Same day purchase and sell.So no profit.') |
| 76 | + return |
| 77 | + |
| 78 | + price_difference = [] |
| 79 | + for day in range(1, len(price)): |
| 80 | + price_difference.append(price[day] - price[day - 1]) |
| 81 | + |
| 82 | + # l is day of purchasing |
| 83 | + # h is day of selling |
| 84 | + # s is profit |
| 85 | + |
| 86 | + l, h, s = max_sub_array(price_difference, 0, (len(price_difference) - 1)) |
| 87 | + if s < 0: |
| 88 | + # if it happens that price drops and never rises to |
| 89 | + # the price when it was purchased |
| 90 | + |
| 91 | + print('No days found to get profit') |
| 92 | + else: |
| 93 | + # To be more real-life oriented we start counting from day-1 instead of |
| 94 | + # day-0 |
| 95 | + |
| 96 | + print('Day of Purchase:', l + 1, |
| 97 | + '\nDay of Selling:', h + 1, |
| 98 | + '\nProfit:', s) |
| 99 | + |
| 100 | + |
| 101 | +if __name__ == '__main__': |
| 102 | + main() |
0 commit comments