From dc97e64bcd7b8f24ae87567dec37504fab82cdb5 Mon Sep 17 00:00:00 2001 From: Ruthie Date: Sun, 14 Nov 2021 13:08:43 -0800 Subject: [PATCH 1/6] adds functionality to newman-conway --- .vscode/settings.json | 7 ++++++ lib/max_subarray.py | 26 +++++++++++++++++++++- lib/newman_conway.py | 52 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9b38853 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} \ No newline at end of file diff --git a/lib/max_subarray.py b/lib/max_subarray.py index 4e892e0..a53861c 100644 --- a/lib/max_subarray.py +++ b/lib/max_subarray.py @@ -5,8 +5,32 @@ def max_sub_array(nums): Time Complexity: ? Space Complexity: ? """ + + #https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/ + #https://www.youtube.com/watch?v=ohHWQf1HDfU + + max_sum = 0 + current_max_sum = 0 + if nums == None: return 0 if len(nums) == 0: return 0 - pass + + #logic: + #set the new calc to previous until you determine if it is <> then previous + + #loop through nums + for i in range(len(nums)-1): + print(f"current_max_sum: {current_max_sum}") + current_max_sum = current_max_sum + nums[i] + print(f"current_max_sum: {current_max_sum}") + + if max_sum < current_max_sum: + max_sum = current_max_sum + print(f"max_sum: {max_sum}") + + return max_sum + + + diff --git a/lib/newman_conway.py b/lib/newman_conway.py index 70a3353..0cb7c19 100644 --- a/lib/newman_conway.py +++ b/lib/newman_conway.py @@ -1,10 +1,56 @@ +#Newman Conway Sequence is the sequence which follows a +#given recursive relation (p(n) = p(p(n-1)) + p(n-p(n-1))) +#to generate a series of numbers. +# Time complexity: ? Should be O(n) becuase processing time will depend on the size of n +# Space Complexity: Space complexity depends on how many memo's are taken? So O(n) maybe? -# Time complexity: ? -# Space Complexity: ? def newman_conway(num): """ Returns a list of the Newman Conway numbers for the given value. Time Complexity: ? Space Complexity: ? """ - pass + + #base case? + if (num <= 0): + #raise a value error? + raise ValueError + + #create memoization array based on the input num + memo = [0] * (num+1) + print(f"memo initial: {memo}") + + #set inital values + memo[0] = 0 + memo[1] = 1 + # memo[2] = 1 + print(f"memo: {memo}") + + # #im not sure how to deal with the cases of 1 and 2 + if num == 1: + return '1' + + # #base case + if (num == 2) : + memo[2] = 1 + return '1 1' + + for i in range(3, num + 1): + print(f"num: {num}") + #(p(n) = p(p(n-1)) + p(n-p(n-1))) + memo[i] = memo[memo[num-1]] + memo[num - memo[num - 1]] + print(f"new num: {num}") + print(f"memo after loop: {memo}") + + return memo + + + # i = 3 + # while (i <= num): + # #collect nc sequence numbers + # memo[i] = memo[memo[i-1]] + memo[i - memo[i -1]] + # i += 1 + + #return memo + + From 7f86a34cc90dabd4537c0eadd9c8cb7da1bf5aed Mon Sep 17 00:00:00 2001 From: Ruthie Date: Wed, 9 Mar 2022 20:04:58 -0800 Subject: [PATCH 2/6] feat: implement max_sub_array method. --- lib/max_subarray.py | 75 ++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/lib/max_subarray.py b/lib/max_subarray.py index a53861c..f7d682c 100644 --- a/lib/max_subarray.py +++ b/lib/max_subarray.py @@ -1,36 +1,55 @@ - -def max_sub_array(nums): +import sys + +#To find the max sum of sub_array which includes values from left, mid and right of the nums array +def max_mid_array(nums, left, mid, right): + + # To find the max sum of the left, iterate backwards + #from the mid num + sum = 0 + left_sum = -sys.maxsize + + for i in range(mid, left-1, -1): + sum = sum + nums[i] + + if (sum > left_sum): + left_sum = sum + + #To find the max sum of right subarray iterate up(increasing index values)from the + #num to the right of mid num(mid + 1). + sum = 0 + right_sum = -sys.maxsize + + for i in range(mid + 1, right + 1): + sum = sum + nums[i] + + if (sum > right_sum): + right_sum = sum + + return (left_sum + right_sum) + +#To find the max subarray +def max_sub_array(nums, left, right): """ Returns the max subarray of the given list of numbers. Returns 0 if nums is None or an empty list. - Time Complexity: ? - Space Complexity: ? + + Time Complexity: Time complexity is O(nLogn) time because of the implementation of a Divide and Conquer approach, in which the max subarray of + the given array is found through comparing the left and right value of a recursively calculated mid-point. This method also recursively calls the + helper method; max_mid_array() which considers max subarrays that range from left to right across the mid-point, with an O(nLogn) time complexity. + + Space Complexity: Space complexity should be O(nLogn) as well because, according to my research, space complexity is relative to the size of the + call stack, which decreases by 2 values with each recursive call. """ - - #https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/ - #https://www.youtube.com/watch?v=ohHWQf1HDfU - - max_sum = 0 - current_max_sum = 0 - - if nums == None: - return 0 if len(nums) == 0: return 0 - - #logic: - #set the new calc to previous until you determine if it is <> then previous - - #loop through nums - for i in range(len(nums)-1): - print(f"current_max_sum: {current_max_sum}") - current_max_sum = current_max_sum + nums[i] - print(f"current_max_sum: {current_max_sum}") - if max_sum < current_max_sum: - max_sum = current_max_sum - print(f"max_sum: {max_sum}") - - return max_sum - + #base case == only one element + if(left == right): + return nums[left] + mid = (left + right) // 2 + maximum_sum_left_subarray = max_sub_array(nums, left, mid) + maximum_sum_right_subarray = max_sub_array(nums, left+1, right) + maximum_sum_crossing_subarray = max_mid_array(nums, left, mid, right); + + return max(maximum_sum_left_subarray, maximum_sum_right_subarray, maximum_sum_crossing_subarray) From 657a6c743a5b16cadfc4f22c3c1dd025ae157a9d Mon Sep 17 00:00:00 2001 From: Ruthie Date: Wed, 9 Mar 2022 20:15:26 -0800 Subject: [PATCH 3/6] test: refactor max_sub_array unit tests to accomodate additional parameters of left and right added to the max_sub_array method in max_subarray.py. --- tests/test_max_sub_array.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/test_max_sub_array.py b/tests/test_max_sub_array.py index cbfb249..7986fdc 100644 --- a/tests/test_max_sub_array.py +++ b/tests/test_max_sub_array.py @@ -1,14 +1,16 @@ from lib.max_subarray import max_sub_array def test_max_subarray_on_empty_array(): - assert max_sub_array([]) == 0 + + assert max_sub_array([], 0, 0) == 0 def test_max_subarray_with_negative_elements(): # Arrange input = [-3, -4, -5, -6, -7] + n = len(input) # Act - answer = max_sub_array(input) + answer = max_sub_array(input, 0, n-1) # Assert assert answer == -3 @@ -16,9 +18,10 @@ def test_max_subarray_with_negative_elements(): def test_max_subarray_with_negative_array_with_largest_element_at_rear(): # Arrange input = [-4, -5, -6, -7, -1] + n = len(input) # Act - answer = max_sub_array(input) + answer = max_sub_array(input, 0, n-1) # Assert assert answer == -1 @@ -26,9 +29,10 @@ def test_max_subarray_with_negative_array_with_largest_element_at_rear(): def test_max_subarray_with_one_element_array(): # Arrange input = [3] + n = len(input) # Act - answer = max_sub_array(input) + answer = max_sub_array(input, 0, n-1) # Assert assert answer == 3 @@ -36,9 +40,10 @@ def test_max_subarray_with_one_element_array(): def test_max_sub_array_with_50_neg_50_50(): # Arrange input = [50, -50, 50] + n = len(input) # Act - answer = max_sub_array(input) + answer = max_sub_array(input, 0, n-1) # Assert assert answer == 50 @@ -46,19 +51,22 @@ def test_max_sub_array_with_50_neg_50_50(): def test_max_sub_array_with_50_3_neg_50_3(): # Arrange input = [50, 3, -50, 50, 3] + n = len(input) # Act - answer = max_sub_array(input) + answer = max_sub_array(input, 0, n-1) # Assert assert answer == 56 def test_max_sub_array_with_50_3_neg_50_10_65_neg_3(): - # Arrange + # Arrange input = [50, 3, -50, 10, 65, -3] + n = len(input) # Act - answer = max_sub_array(input) + answer = max_sub_array(input, 0, n-1) # Assert assert answer == 78 # 50, 3, -50, 10, 65 (largest subarray) + \ No newline at end of file From 40f8fc0b5302c83da97c9ba40c7fc8ce0ff89b63 Mon Sep 17 00:00:00 2001 From: Ruthie Date: Wed, 9 Mar 2022 22:32:14 -0800 Subject: [PATCH 4/6] feat: implement newman_conway method. --- lib/newman_conway.py | 59 ++++++++++++-------------------------------- 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/lib/newman_conway.py b/lib/newman_conway.py index 0cb7c19..27d6cad 100644 --- a/lib/newman_conway.py +++ b/lib/newman_conway.py @@ -1,56 +1,29 @@ -#Newman Conway Sequence is the sequence which follows a -#given recursive relation (p(n) = p(p(n-1)) + p(n-p(n-1))) -#to generate a series of numbers. - -# Time complexity: ? Should be O(n) becuase processing time will depend on the size of n -# Space Complexity: Space complexity depends on how many memo's are taken? So O(n) maybe? def newman_conway(num): """ Returns a list of the Newman Conway numbers for the given value. - Time Complexity: ? - Space Complexity: ? + Time Complexity: O(n) because the number of calculations performed depends on the size of num. + + Space Complexity: Space complexity is also O(n) becuase newman_conway_nums array to store sequence values, + nm_sequence_without_leading_zero to store result with leading 0 removed and result a array to which the properly + formatted result is saved are created and the amount of space that they occupy will depend on the size of the given num. """ - - #base case? - if (num <= 0): - #raise a value error? + if num == 0: raise ValueError - - #create memoization array based on the input num - memo = [0] * (num+1) - print(f"memo initial: {memo}") - - #set inital values - memo[0] = 0 - memo[1] = 1 - # memo[2] = 1 - print(f"memo: {memo}") - - # #im not sure how to deal with the cases of 1 and 2 + if num == 1: return '1' - # #base case - if (num == 2) : - memo[2] = 1 + if num == 2: return '1 1' - - for i in range(3, num + 1): - print(f"num: {num}") - #(p(n) = p(p(n-1)) + p(n-p(n-1))) - memo[i] = memo[memo[num-1]] + memo[num - memo[num - 1]] - print(f"new num: {num}") - print(f"memo after loop: {memo}") - return memo - + #array to store sequence values and provide starting values + newman_conway_nums = [0, 1, 1] - # i = 3 - # while (i <= num): - # #collect nc sequence numbers - # memo[i] = memo[memo[i-1]] + memo[i - memo[i -1]] - # i += 1 + for i in range(3, num + 1): + newman_conway_nums.append(newman_conway_nums[newman_conway_nums[i-1]] + newman_conway_nums[i-newman_conway_nums[i-1]]) - #return memo - + nm_sequence_without_leading_zero = [str(num) for num in newman_conway_nums if num != 0] + result = " ".join(nm_sequence_without_leading_zero) + return result + From 5d44d2dc6d866dbdf8c6d7db92736fa3fdfed5ab Mon Sep 17 00:00:00 2001 From: Ruthie Date: Thu, 10 Mar 2022 19:32:53 -0800 Subject: [PATCH 5/6] refactor: add default values for max_sub_array method parameters. --- lib/max_subarray.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/max_subarray.py b/lib/max_subarray.py index f7d682c..20f6eef 100644 --- a/lib/max_subarray.py +++ b/lib/max_subarray.py @@ -28,7 +28,7 @@ def max_mid_array(nums, left, mid, right): return (left_sum + right_sum) #To find the max subarray -def max_sub_array(nums, left, right): +def max_sub_array(nums, left=0, right=None): """ Returns the max subarray of the given list of numbers. Returns 0 if nums is None or an empty list. @@ -39,9 +39,14 @@ def max_sub_array(nums, left, right): Space Complexity: Space complexity should be O(nLogn) as well because, according to my research, space complexity is relative to the size of the call stack, which decreases by 2 values with each recursive call. """ - if len(nums) == 0: + n = len(nums) + + if n == 0: return 0 + if right == None: + right = n-1 + #base case == only one element if(left == right): return nums[left] From d119db0631ca68eec3a7183def36bcc5076a26c6 Mon Sep 17 00:00:00 2001 From: Ruthie Date: Thu, 10 Mar 2022 19:34:08 -0800 Subject: [PATCH 6/6] test: revise max_sub_array unit tests to test functionality of refactored max_sub_array method. --- tests/test_max_sub_array.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_max_sub_array.py b/tests/test_max_sub_array.py index 7986fdc..4b564a8 100644 --- a/tests/test_max_sub_array.py +++ b/tests/test_max_sub_array.py @@ -2,7 +2,7 @@ def test_max_subarray_on_empty_array(): - assert max_sub_array([], 0, 0) == 0 + assert max_sub_array([]) == 0 def test_max_subarray_with_negative_elements(): # Arrange @@ -10,7 +10,7 @@ def test_max_subarray_with_negative_elements(): n = len(input) # Act - answer = max_sub_array(input, 0, n-1) + answer = max_sub_array(input) # Assert assert answer == -3 @@ -21,7 +21,7 @@ def test_max_subarray_with_negative_array_with_largest_element_at_rear(): n = len(input) # Act - answer = max_sub_array(input, 0, n-1) + answer = max_sub_array(input) # Assert assert answer == -1 @@ -32,7 +32,7 @@ def test_max_subarray_with_one_element_array(): n = len(input) # Act - answer = max_sub_array(input, 0, n-1) + answer = max_sub_array(input) # Assert assert answer == 3 @@ -43,7 +43,7 @@ def test_max_sub_array_with_50_neg_50_50(): n = len(input) # Act - answer = max_sub_array(input, 0, n-1) + answer = max_sub_array(input) # Assert assert answer == 50 @@ -54,7 +54,7 @@ def test_max_sub_array_with_50_3_neg_50_3(): n = len(input) # Act - answer = max_sub_array(input, 0, n-1) + answer = max_sub_array(input) # Assert assert answer == 56 @@ -65,7 +65,7 @@ def test_max_sub_array_with_50_3_neg_50_10_65_neg_3(): n = len(input) # Act - answer = max_sub_array(input, 0, n-1) + answer = max_sub_array(input) # Assert assert answer == 78 # 50, 3, -50, 10, 65 (largest subarray)