From 82f69fd2c3ea5b120ff856973f0511eb867acd48 Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Fri, 12 Mar 2021 09:39:33 +0530 Subject: [PATCH 01/11] upper_bound and lower_bound functions added --- .../linear_data_structures/__init__.py | 6 +- .../linear_data_structures/algorithms.py | 107 +++++++++++++++++- .../tests/test_algorithms.py | 48 +++++++- 3 files changed, 156 insertions(+), 5 deletions(-) diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index da3eedda2..149254113 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -32,6 +32,8 @@ bucket_sort, cocktail_shaker_sort, quick_sort, - longest_common_subsequence -) + longest_common_subsequence, + upper_bound, + lower_bound + ) __all__.extend(algorithms.__all__) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index c6022c1ff..a93bb492e 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -14,8 +14,10 @@ 'bucket_sort', 'cocktail_shaker_sort', 'quick_sort', - 'longest_common_subsequence' -] + 'longest_common_subsequence', + 'upper_bound', + 'lower_bound' + ] def _merge(array, sl, el, sr, er, end, comp): l, r = [], [] @@ -787,3 +789,104 @@ def longest_common_subsequence(seq1: OneDimensionalArray, seq2: OneDimensionalAr check_mat[i][j] = check_mat[i][j-1] return OneDimensionalArray(seq1._dtype, check_mat[row][col][-1]) + +def upper_bound(array, start, end, value): + """ + Finds the index of the first occurence of an element greater than value,in the given sorted OneDimensionalArray + + Parameters + ======== + array: OneDimensionalArray + The sorted array in which the upper bound has to be found + + start: int + The staring index of the portion of the array in which the upper bound of a given value has to be looked for + + end: int + The ending index of the portion of the array in which the upper bound of a given value has to be looked for + + Returns + ======= + + output: int + Upper bound of the given value in the given sorted OneDimensionalArray + + Examples + ======== + >>> from pydatastructs import upper_bound, OneDimensionalArray as ODA + >>> arr = ODA(int, [4, 5, 5, 6, 7]) + >>> upperBound = upper_bound(arr, 0, 4, 5) + >>> upperBound + 3 + >>> arr = ODA(int, [4, 5, 5, 6, 7]) + >>> upperBound = upper_bound(arr, 0, 4, 4) + >>> upperBound + 1 + + Note + ==== + + The OneDimensionalArray must be sorted beforehand + """ + index = end + if array[start] > value: + index = start + while start <= end: + mid = (start+end)//2 + if array[mid] <= value: + start = mid+1 + else: + index = mid + end = mid-1 + return index + +def lower_bound(array, start, end, value): + """ + Finds the the index of the first occurence of an element which is not less than value, in the given OneDimensionalArray + + Parameters + ======== + array: OneDimensionalArray + The sorted array in which the lower bound has to be found + + start: int + The staring index of the portion of the array in which the lower bound of a given value has to be looked for + + end: int + The ending index of the portion of the array in which the lower bound of a given value has to be looked for + + Returns + ======= + + output: int + Lower bound of the given value in the given sorted OneDimensionalArray + + Examples + ======== + + >>> from pydatastructs import lower_bound, OneDimensionalArray as ODA + >>> arr = ODA(int, [4, 5, 5, 6, 7]) + >>> lowerBound = lower_bound(arr, 0, 4, 5) + >>> lowerBound + 1 + >>> arr = ODA(int, [4, 5, 5, 6, 7]) + >>> lowerBound = lower_bound(arr, 0, 4, 6) + >>> lowerBound + 3 + + Note + ==== + + The OneDimensionalArray must be sorted beforehand + """ + index = end + if array[start] > value: + index = start + while start <= end: + mid = (start+end)//2 + if array[mid] < value: + start = mid + 1 + else: + index = mid + end = mid -1 + return index diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index f50a3da89..7605c5975 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -1,7 +1,8 @@ from pydatastructs import ( merge_sort_parallel, DynamicOneDimensionalArray, OneDimensionalArray, brick_sort, brick_sort_parallel, - heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort, quick_sort, longest_common_subsequence) + heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort, quick_sort, longest_common_subsequence, + upper_bound, lower_bound) from pydatastructs.utils.raises_util import raises @@ -126,3 +127,48 @@ def test_longest_common_sequence(): Z = ODA(int, []) output = longest_common_subsequence(Y, Z) assert str(output) == '[]' + +def test_upper_bound(): + ODA = OneDimensionalArray + arr1 = ODA(int, [3, 3, 3]) + output = upper_bound(arr1, 0, len(arr1)-1, 3) + expected_result = 2 + assert expected_result == output + + arr2 = ODA(int, [4, 4, 5, 6]) + output = upper_bound(arr2, 0, len(arr2)-1, 4) + expected_result = 2 + assert expected_result == output + + arr3 = ODA(int, [6, 6, 7, 8, 9]) + output = upper_bound(arr3, 0, len(arr3)-1, 5) + expected_result = 0 + assert expected_result == output + + arr4 = ODA(int, [3, 4, 4]) + output = upper_bound(arr4, 0, len(arr4)-1, 5) + expected_result = 2 + assert expected_result == output + + +def test_lower_bound(): + ODA = OneDimensionalArray + arr1 = ODA(int, [3, 3, 3]) + output = lower_bound(arr1, 0, len(arr1)-1, 3) + expected_result = 0 + assert expected_result == output + + arr2 = ODA(int, [4, 4, 5, 6]) + output = lower_bound(arr2, 0, len(arr2)-1, 5) + expected_result = 2 + assert expected_result == output + + arr3 = ODA(int, [6, 6, 7, 8, 9]) + output = lower_bound(arr3, 0, len(arr3)-1, 5) + expected_result = 0 + assert expected_result == output + + arr4 = ODA(int, [3, 4, 4]) + output = lower_bound(arr4, 0, len(arr4)-1, 5) + expected_result = 2 + assert expected_result == output From 03adc0de740bad07c304351d60de1670891d05c3 Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Sat, 13 Mar 2021 21:22:30 +0530 Subject: [PATCH 02/11] upper_bound and lower_bound functions changed --- .../linear_data_structures/algorithms.py | 44 ++++++++++-------- .../tests/test_algorithms.py | 46 +++++++++++++++---- 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index a93bb492e..155c59b63 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -790,14 +790,14 @@ def longest_common_subsequence(seq1: OneDimensionalArray, seq2: OneDimensionalAr return OneDimensionalArray(seq1._dtype, check_mat[row][col][-1]) -def upper_bound(array, start, end, value): +def upper_bound(array, start, end, value, comp): """ - Finds the index of the first occurence of an element greater than value,in the given sorted OneDimensionalArray + Finds the index of the first occurence of an element greater than value according to an order defined,in the given sorted OneDimensionalArray Parameters ======== array: OneDimensionalArray - The sorted array in which the upper bound has to be found + The sorted array (sorted according to a custom comparator function) in which the upper bound has to be found start: int The staring index of the portion of the array in which the upper bound of a given value has to be looked for @@ -815,39 +815,41 @@ def upper_bound(array, start, end, value): ======== >>> from pydatastructs import upper_bound, OneDimensionalArray as ODA >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> upperBound = upper_bound(arr, 0, 4, 5) + >>> upperBound = upper_bound(arr, 0, 4, 5, None) >>> upperBound 3 - >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> upperBound = upper_bound(arr, 0, 4, 4) + >>> arr = ODA(int, [7, 6, 5, 5, 4]) + >>> upperBound = upper_bound(arr, 0, 4, 5, lambda x, y: x >= y) >>> upperBound - 1 + 4 Note ==== The OneDimensionalArray must be sorted beforehand """ + if comp is None: + comp = lambda a, b: (a <= b) index = end - if array[start] > value: + if not comp(array[start], value): index = start while start <= end: mid = (start+end)//2 - if array[mid] <= value: - start = mid+1 + if comp(array[mid],value): + start = mid + 1 else: index = mid - end = mid-1 + end = mid -1 return index -def lower_bound(array, start, end, value): +def lower_bound(array, start, end, value, comp): """ - Finds the the index of the first occurence of an element which is not less than value, in the given OneDimensionalArray + Finds the the index of the first occurence of an element which is not less than value according to an order defined, in the given OneDimensionalArray Parameters ======== array: OneDimensionalArray - The sorted array in which the lower bound has to be found + The sorted array (sorted according to a custom comparator function) in which the lower bound has to be found start: int The staring index of the portion of the array in which the lower bound of a given value has to be looked for @@ -866,25 +868,27 @@ def lower_bound(array, start, end, value): >>> from pydatastructs import lower_bound, OneDimensionalArray as ODA >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> lowerBound = lower_bound(arr, 0, 4, 5) + >>> lowerBound = lower_bound(arr, 0, 4, 5, lambda x, y : x < y) >>> lowerBound 1 - >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> lowerBound = lower_bound(arr, 0, 4, 6) + >>> arr = ODA(int, [7, 6, 5, 5, 4]) + >>> lowerBound = lower_bound(arr, 0, 4, 5, lambda x, y : x > y) >>> lowerBound - 3 + 2 Note ==== The OneDimensionalArray must be sorted beforehand """ + if comp is None: + comp = lambda a, b: (a < b) index = end - if array[start] > value: + if not comp(array[start], value): index = start while start <= end: mid = (start+end)//2 - if array[mid] < value: + if comp(array[mid],value): start = mid + 1 else: index = mid diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 7605c5975..1f7502593 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -131,44 +131,74 @@ def test_longest_common_sequence(): def test_upper_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = upper_bound(arr1, 0, len(arr1)-1, 3) + output = upper_bound(arr1, 0, len(arr1)-1, 3, None) expected_result = 2 assert expected_result == output arr2 = ODA(int, [4, 4, 5, 6]) - output = upper_bound(arr2, 0, len(arr2)-1, 4) + output = upper_bound(arr2, 0, len(arr2)-1, 4, None) expected_result = 2 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = upper_bound(arr3, 0, len(arr3)-1, 5) + output = upper_bound(arr3, 0, len(arr3)-1, 5, None) expected_result = 0 assert expected_result == output arr4 = ODA(int, [3, 4, 4]) - output = upper_bound(arr4, 0, len(arr4)-1, 5) + output = upper_bound(arr4, 0, len(arr4)-1, 5, None) expected_result = 2 assert expected_result == output + arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = upper_bound(arr5, 0, len(arr5)-1, 6, lambda x, y: x >= y) + expected_result = 5 + assert expected_result == output + + arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = upper_bound(arr6, 0, len(arr6)-1, 2, lambda x, y: x >= y) + expected_result = 7 + assert expected_result == output + + arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = upper_bound(arr7, 0, len(arr7)-1, 9, lambda x, y: x >= y) + expected_result = 0 + assert expected_result == output + def test_lower_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = lower_bound(arr1, 0, len(arr1)-1, 3) + output = lower_bound(arr1, 0, len(arr1)-1, 3, None) expected_result = 0 assert expected_result == output arr2 = ODA(int, [4, 4, 5, 6]) - output = lower_bound(arr2, 0, len(arr2)-1, 5) + output = lower_bound(arr2, 0, len(arr2)-1, 5, None) expected_result = 2 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = lower_bound(arr3, 0, len(arr3)-1, 5) + output = lower_bound(arr3, 0, len(arr3)-1, 5, None) expected_result = 0 assert expected_result == output arr4 = ODA(int, [3, 4, 4]) - output = lower_bound(arr4, 0, len(arr4)-1, 5) + output = lower_bound(arr4, 0, len(arr4)-1, 5, None) expected_result = 2 assert expected_result == output + + arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = lower_bound(arr5, 0, len(arr5)-1, 5, lambda x, y: x > y) + expected_result = 5 + assert expected_result == output + + arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = lower_bound(arr6, 0, len(arr6)-1, 2, lambda x, y: x > y) + expected_result = 7 + assert expected_result == output + + arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = lower_bound(arr7, 0, len(arr7)-1, 9, lambda x, y: x > y) + expected_result = 0 + assert expected_result == output From bee4f49c485ec3b8f3668c85f242fadcca9ad074 Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Sat, 13 Mar 2021 22:52:03 +0530 Subject: [PATCH 03/11] upper_bound updated and refactored --- .../linear_data_structures/algorithms.py | 42 +++++++++++-------- .../tests/test_algorithms.py | 28 ++++++------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 155c59b63..278e9ea42 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -792,24 +792,28 @@ def longest_common_subsequence(seq1: OneDimensionalArray, seq2: OneDimensionalAr def upper_bound(array, start, end, value, comp): """ - Finds the index of the first occurence of an element greater than value according to an order defined,in the given sorted OneDimensionalArray + Finds the index of the first occurence of an element greater than value according + to an order defined,in the given sorted OneDimensionalArray Parameters ======== array: OneDimensionalArray - The sorted array (sorted according to a custom comparator function) in which the upper bound has to be found + The sorted array (sorted according to a custom comparator function) in which the + upper bound has to be found start: int - The staring index of the portion of the array in which the upper bound of a given value has to be looked for + The staring index of the portion of the array in which the upper bound + of a given value has to be looked for end: int - The ending index of the portion of the array in which the upper bound of a given value has to be looked for + The ending index of the portion of the array in which the upper bound + of a given value has to be looked for Returns ======= output: int - Upper bound of the given value in the given sorted OneDimensionalArray + Upper bound of the given value in the given sorted OneDimensionalArray Examples ======== @@ -819,7 +823,7 @@ def upper_bound(array, start, end, value, comp): >>> upperBound 3 >>> arr = ODA(int, [7, 6, 5, 5, 4]) - >>> upperBound = upper_bound(arr, 0, 4, 5, lambda x, y: x >= y) + >>> upperBound = upper_bound(arr, 0, 4, 5, lambda x, y: x > y) >>> upperBound 4 @@ -829,13 +833,13 @@ def upper_bound(array, start, end, value, comp): The OneDimensionalArray must be sorted beforehand """ if comp is None: - comp = lambda a, b: (a <= b) + comp = lambda a, b: (a < b) index = end - if not comp(array[start], value): + if comp(value, array[start]): index = start while start <= end: - mid = (start+end)//2 - if comp(array[mid],value): + mid = (start + end)//2 + if not comp(value, array[mid]): start = mid + 1 else: index = mid @@ -844,24 +848,28 @@ def upper_bound(array, start, end, value, comp): def lower_bound(array, start, end, value, comp): """ - Finds the the index of the first occurence of an element which is not less than value according to an order defined, in the given OneDimensionalArray + Finds the the index of the first occurence of an element which is not + less than value according to an order defined, in the given OneDimensionalArray Parameters ======== array: OneDimensionalArray - The sorted array (sorted according to a custom comparator function) in which the lower bound has to be found + The sorted array (sorted according to a custom comparator function) + in which the lower bound has to be found start: int - The staring index of the portion of the array in which the lower bound of a given value has to be looked for + The staring index of the portion of the array in which the lower + bound of a given value has to be looked for end: int - The ending index of the portion of the array in which the lower bound of a given value has to be looked for + The ending index of the portion of the array in which the lower + bound of a given value has to be looked for Returns ======= output: int - Lower bound of the given value in the given sorted OneDimensionalArray + Lower bound of the given value in the given sorted OneDimensionalArray Examples ======== @@ -887,8 +895,8 @@ def lower_bound(array, start, end, value, comp): if not comp(array[start], value): index = start while start <= end: - mid = (start+end)//2 - if comp(array[mid],value): + mid = (start + end)//2 + if comp(array[mid], value): start = mid + 1 else: index = mid diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 1f7502593..0279a86b9 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -131,37 +131,37 @@ def test_longest_common_sequence(): def test_upper_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = upper_bound(arr1, 0, len(arr1)-1, 3, None) + output = upper_bound(arr1, 0, len(arr1) - 1, 3, None) expected_result = 2 assert expected_result == output arr2 = ODA(int, [4, 4, 5, 6]) - output = upper_bound(arr2, 0, len(arr2)-1, 4, None) + output = upper_bound(arr2, 0, len(arr2) - 1, 4, None) expected_result = 2 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = upper_bound(arr3, 0, len(arr3)-1, 5, None) + output = upper_bound(arr3, 0, len(arr3) - 1, 5, None) expected_result = 0 assert expected_result == output arr4 = ODA(int, [3, 4, 4]) - output = upper_bound(arr4, 0, len(arr4)-1, 5, None) + output = upper_bound(arr4, 0, len(arr4) - 1, 5, None) expected_result = 2 assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr5, 0, len(arr5)-1, 6, lambda x, y: x >= y) + output = upper_bound(arr5, 0, len(arr5) - 1, 6, lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr6, 0, len(arr6)-1, 2, lambda x, y: x >= y) + output = upper_bound(arr6, 0, len(arr6) - 1, 2, lambda x, y: x > y) expected_result = 7 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr7, 0, len(arr7)-1, 9, lambda x, y: x >= y) + output = upper_bound(arr7, 0, len(arr7) - 1, 9, lambda x, y: x > y) expected_result = 0 assert expected_result == output @@ -169,36 +169,36 @@ def test_upper_bound(): def test_lower_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = lower_bound(arr1, 0, len(arr1)-1, 3, None) + output = lower_bound(arr1, 0, len(arr1) - 1, 3, None) expected_result = 0 assert expected_result == output arr2 = ODA(int, [4, 4, 5, 6]) - output = lower_bound(arr2, 0, len(arr2)-1, 5, None) + output = lower_bound(arr2, 0, len(arr2) - 1, 5, None) expected_result = 2 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = lower_bound(arr3, 0, len(arr3)-1, 5, None) + output = lower_bound(arr3, 0, len(arr3) - 1, 5, None) expected_result = 0 assert expected_result == output arr4 = ODA(int, [3, 4, 4]) - output = lower_bound(arr4, 0, len(arr4)-1, 5, None) + output = lower_bound(arr4, 0, len(arr4) - 1, 5, None) expected_result = 2 assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr5, 0, len(arr5)-1, 5, lambda x, y: x > y) + output = lower_bound(arr5, 0, len(arr5) - 1, 5, lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr6, 0, len(arr6)-1, 2, lambda x, y: x > y) + output = lower_bound(arr6, 0, len(arr6) - 1, 2, lambda x, y: x > y) expected_result = 7 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr7, 0, len(arr7)-1, 9, lambda x, y: x > y) + output = lower_bound(arr7, 0, len(arr7) - 1, 9, lambda x, y: x > y) expected_result = 0 assert expected_result == output From ac94fbca4ccfa746df42a26b8235b75f829374cb Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Sat, 13 Mar 2021 23:12:29 +0530 Subject: [PATCH 04/11] minor refactoring --- pydatastructs/linear_data_structures/algorithms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 278e9ea42..56b96900d 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -843,7 +843,7 @@ def upper_bound(array, start, end, value, comp): start = mid + 1 else: index = mid - end = mid -1 + end = mid - 1 return index def lower_bound(array, start, end, value, comp): @@ -900,5 +900,5 @@ def lower_bound(array, start, end, value, comp): start = mid + 1 else: index = mid - end = mid -1 + end = mid - 1 return index From f412327d412049a3f67fad1a5d3aae457943d2a5 Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Thu, 18 Mar 2021 15:58:12 +0530 Subject: [PATCH 05/11] interval changed from closed to semi-open --- .../linear_data_structures/algorithms.py | 18 +++--- .../tests/test_algorithms.py | 62 +++++++++++-------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 56b96900d..00163d503 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -813,7 +813,7 @@ def upper_bound(array, start, end, value, comp): ======= output: int - Upper bound of the given value in the given sorted OneDimensionalArray + Index of the upper bound of the given value in the given sorted OneDimensionalArray Examples ======== @@ -835,15 +835,16 @@ def upper_bound(array, start, end, value, comp): if comp is None: comp = lambda a, b: (a < b) index = end + inclusiveEnd = end - 1 if comp(value, array[start]): index = start - while start <= end: - mid = (start + end)//2 + while start <= inclusiveEnd: + mid = (start + inclusiveEnd)//2 if not comp(value, array[mid]): start = mid + 1 else: index = mid - end = mid - 1 + inclusiveEnd = mid - 1 return index def lower_bound(array, start, end, value, comp): @@ -869,7 +870,7 @@ def lower_bound(array, start, end, value, comp): ======= output: int - Lower bound of the given value in the given sorted OneDimensionalArray + Index of the lower bound of the given value in the given sorted OneDimensionalArray Examples ======== @@ -892,13 +893,14 @@ def lower_bound(array, start, end, value, comp): if comp is None: comp = lambda a, b: (a < b) index = end + inclusiveEnd = end - 1 if not comp(array[start], value): index = start - while start <= end: - mid = (start + end)//2 + while start <= inclusiveEnd: + mid = (start + inclusiveEnd)//2 if comp(array[mid], value): start = mid + 1 else: index = mid - end = mid - 1 + inclusiveEnd = mid - 1 return index diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 0279a86b9..755c288cc 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -131,74 +131,84 @@ def test_longest_common_sequence(): def test_upper_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = upper_bound(arr1, 0, len(arr1) - 1, 3, None) - expected_result = 2 + output = upper_bound(arr1, 0, len(arr1), 3, None) + expected_result = 3 assert expected_result == output arr2 = ODA(int, [4, 4, 5, 6]) - output = upper_bound(arr2, 0, len(arr2) - 1, 4, None) + output = upper_bound(arr2, 0, 3, 4, None) expected_result = 2 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = upper_bound(arr3, 0, len(arr3) - 1, 5, None) - expected_result = 0 + output = upper_bound(arr3, 2, 4, 5, None) + expected_result = 2 assert expected_result == output - arr4 = ODA(int, [3, 4, 4]) - output = upper_bound(arr4, 0, len(arr4) - 1, 5, None) - expected_result = 2 + arr4 = ODA(int, [3, 4, 4, 6]) + output = upper_bound(arr4, 1, 3, 5, None) + expected_result = 3 assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr5, 0, len(arr5) - 1, 6, lambda x, y: x > y) + output = upper_bound(arr5, 0, len(arr5), 6, lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr6, 0, len(arr6) - 1, 2, lambda x, y: x > y) - expected_result = 7 + output = upper_bound(arr6, 2, len(arr6), 2, lambda x, y: x > y) + expected_result = 8 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr7, 0, len(arr7) - 1, 9, lambda x, y: x > y) - expected_result = 0 + output = upper_bound(arr7, 3, 7, 9, lambda x, y: x > y) + expected_result = 3 + assert expected_result == output + + arr8 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = upper_bound(arr8, 0, 3, 6, lambda x, y: x > y) + expected_result = 3 assert expected_result == output def test_lower_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = lower_bound(arr1, 0, len(arr1) - 1, 3, None) - expected_result = 0 + output = lower_bound(arr1, 1, len(arr1), 3, None) + expected_result = 1 assert expected_result == output - arr2 = ODA(int, [4, 4, 5, 6]) - output = lower_bound(arr2, 0, len(arr2) - 1, 5, None) - expected_result = 2 + arr2 = ODA(int, [4, 4, 4, 4, 5, 6]) + output = lower_bound(arr2, 0, 3, 5, None) + expected_result = 3 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = lower_bound(arr3, 0, len(arr3) - 1, 5, None) + output = lower_bound(arr3, 0, 3, 5, None) expected_result = 0 assert expected_result == output - arr4 = ODA(int, [3, 4, 4]) - output = lower_bound(arr4, 0, len(arr4) - 1, 5, None) - expected_result = 2 + arr4 = ODA(int, [3, 4, 4, 4]) + output = lower_bound(arr4, 0, 4, 5, None) + expected_result = 4 assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr5, 0, len(arr5) - 1, 5, lambda x, y: x > y) + output = lower_bound(arr5, 0, len(arr5), 5, lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr6, 0, len(arr6) - 1, 2, lambda x, y: x > y) - expected_result = 7 + output = lower_bound(arr6, 4, len(arr6), 2, lambda x, y: x > y) + expected_result = 8 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr7, 0, len(arr7) - 1, 9, lambda x, y: x > y) + output = lower_bound(arr7, 0, 5, 9, lambda x, y: x > y) expected_result = 0 assert expected_result == output + + arr8 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) + output = lower_bound(arr8, 0, 3, 6, lambda x, y: x > y) + expected_result = 1 + assert expected_result == output From d83de0c3847da85237d6c8ca461a569bbc86c383 Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Wed, 24 Mar 2021 01:56:16 +0530 Subject: [PATCH 06/11] variable arguements added --- .../linear_data_structures/algorithms.py | 30 ++++++--- .../tests/test_algorithms.py | 66 +++++++++---------- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 87308ef4b..651a1cec8 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -794,8 +794,10 @@ def longest_common_subsequence(seq1: OneDimensionalArray, seq2: OneDimensionalAr def is_ordered(array, **kwargs): """ Checks whether the given array is ordered or not. + Parameters ========== + array: Array The array which is to be checked for having specified ordering among its elements. @@ -814,6 +816,7 @@ def is_ordered(array, **kwargs): Optional, by default, less than or equal to is used for comparing two values. + Examples ======== >>> from pydatastructs import OneDimensionalArray, is_ordered @@ -823,6 +826,7 @@ def is_ordered(array, **kwargs): >>> arr1 = OneDimensionalArray(int, [1, 2, 3]) >>> is_ordered(arr1, start=0, end=1, comp=lambda u, v: u > v) False + """ lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) @@ -835,7 +839,7 @@ def is_ordered(array, **kwargs): return False return True -def upper_bound(array, start, end, value, comp): +def upper_bound(array, value, **kwargs): """ Finds the index of the first occurence of an element greater than value according to an order defined,in the given sorted OneDimensionalArray @@ -864,11 +868,11 @@ def upper_bound(array, start, end, value, comp): ======== >>> from pydatastructs import upper_bound, OneDimensionalArray as ODA >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> upperBound = upper_bound(arr, 0, 4, 5, None) + >>> upperBound = upper_bound(arr, 5, start = 0, end = 4) >>> upperBound 3 >>> arr = ODA(int, [7, 6, 5, 5, 4]) - >>> upperBound = upper_bound(arr, 0, 4, 5, lambda x, y: x > y) + >>> upperBound = upper_bound(arr, 5, comp = lambda x, y: x > y) >>> upperBound 4 @@ -877,8 +881,11 @@ def upper_bound(array, start, end, value, comp): The OneDimensionalArray must be sorted beforehand """ - if comp is None: - comp = lambda a, b: (a < b) + start = kwargs.get('start', 0) + end = kwargs.get('end', len(array)) + comp = kwargs.get('comp', lambda x,y: x < y) + # if comp is None: + # comp = lambda a, b: (a < b) index = end inclusive_end = end - 1 if comp(value, array[start]): @@ -892,7 +899,7 @@ def upper_bound(array, start, end, value, comp): inclusive_end = mid - 1 return index -def lower_bound(array, start, end, value, comp): +def lower_bound(array, value, **kwargs): """ Finds the the index of the first occurence of an element which is not less than value according to an order defined, in the given OneDimensionalArray @@ -921,11 +928,11 @@ def lower_bound(array, start, end, value, comp): >>> from pydatastructs import lower_bound, OneDimensionalArray as ODA >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> lowerBound = lower_bound(arr, 0, 4, 5, lambda x, y : x < y) + >>> lowerBound = lower_bound(arr, 5, end = 4, comp = lambda x, y : x < y) >>> lowerBound 1 >>> arr = ODA(int, [7, 6, 5, 5, 4]) - >>> lowerBound = lower_bound(arr, 0, 4, 5, lambda x, y : x > y) + >>> lowerBound = lower_bound(arr, 5, start = 0, comp = lambda x, y : x > y) >>> lowerBound 2 @@ -934,8 +941,11 @@ def lower_bound(array, start, end, value, comp): The OneDimensionalArray must be sorted beforehand """ - if comp is None: - comp = lambda a, b: (a < b) + start = kwargs.get('start', 0) + end = kwargs.get('end', len(array)) + comp = kwargs.get('comp', lambda x, y: x < y) + # if comp is None: + # comp = lambda a, b: (a < b) index = end inclusive_end = end - 1 if not comp(array[start], value): diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index dadad9d03..0d5f4bed7 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -128,74 +128,74 @@ def test_longest_common_sequence(): assert str(output) == '[]' def test_is_ordered(): - ODA=OneDimensionalArray - DODA=DynamicOneDimensionalArray + ODA = OneDimensionalArray + DODA = DynamicOneDimensionalArray - expected_result=True - arr=ODA(int, [1, 2, 5, 6]) - output=is_ordered(arr) + expected_result = True + arr = ODA(int, [1, 2, 5, 6]) + output = is_ordered(arr) assert output == expected_result - expected_result=False - arr1=ODA(int, [4, 3, 2, 1]) - output=is_ordered(arr1) + expected_result = False + arr1 = ODA(int, [4, 3, 2, 1]) + output = is_ordered(arr1) assert output == expected_result - expected_result=True - arr2=ODA(int, [6, 1, 2, 3, 4, 5]) - output=is_ordered(arr2, start=1, end=5) + expected_result = True + arr2 = ODA(int, [6, 1, 2, 3, 4, 5]) + output = is_ordered(arr2, start=1, end=5) assert output == expected_result - expected_result=True - arr3=ODA(int, [0, -1, -2, -3, -4, 4]) - output=is_ordered(arr3, start=1, end=4, comp=lambda u, v: u > v) + expected_result = True + arr3 = ODA(int, [0, -1, -2, -3, -4, 4]) + output = is_ordered(arr3, start = 1, end = 4, comp = lambda u, v: u > v) assert output == expected_result - expected_result=True - arr4=DODA(int, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + expected_result = True + arr4 = DODA(int, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) arr4.delete(0) - output=is_ordered(arr4) + output = is_ordered(arr4) assert output == expected_result def test_upper_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = upper_bound(arr1, 0, len(arr1), 3, None) + output = upper_bound(arr1, 3) expected_result = 3 assert expected_result == output arr2 = ODA(int, [4, 4, 5, 6]) - output = upper_bound(arr2, 0, 3, 4, None) + output = upper_bound(arr2, 4, end = 3) expected_result = 2 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = upper_bound(arr3, 2, 4, 5, None) + output = upper_bound(arr3, 5, start = 2, end = 4) expected_result = 2 assert expected_result == output arr4 = ODA(int, [3, 4, 4, 6]) - output = upper_bound(arr4, 1, 3, 5, None) + output = upper_bound(arr4, 5, start = 1, end = 3) expected_result = 3 assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr5, 0, len(arr5), 6, lambda x, y: x > y) + output = upper_bound(arr5, 6, comp = lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr6, 2, len(arr6), 2, lambda x, y: x > y) + output = upper_bound(arr6, 2, start = 2, comp = lambda x, y: x > y) expected_result = 8 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr7, 3, 7, 9, lambda x, y: x > y) + output = upper_bound(arr7, 9, start = 3, end = 7, comp = lambda x, y: x > y) expected_result = 3 assert expected_result == output arr8 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr8, 0, 3, 6, lambda x, y: x > y) + output = upper_bound(arr8, 6, end = 3, comp = lambda x, y: x > y) expected_result = 3 assert expected_result == output @@ -203,41 +203,41 @@ def test_upper_bound(): def test_lower_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = lower_bound(arr1, 1, len(arr1), 3, None) + output = lower_bound(arr1, 3, start = 1) expected_result = 1 assert expected_result == output arr2 = ODA(int, [4, 4, 4, 4, 5, 6]) - output = lower_bound(arr2, 0, 3, 5, None) + output = lower_bound(arr2, 5, end = 3) expected_result = 3 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = lower_bound(arr3, 0, 3, 5, None) + output = lower_bound(arr3, 5, end = 3) expected_result = 0 assert expected_result == output arr4 = ODA(int, [3, 4, 4, 4]) - output = lower_bound(arr4, 0, 4, 5, None) + output = lower_bound(arr4, 5) expected_result = 4 assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr5, 0, len(arr5), 5, lambda x, y: x > y) + output = lower_bound(arr5, 5, comp = lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr6, 4, len(arr6), 2, lambda x, y: x > y) + output = lower_bound(arr6, 2, start = 4, comp = lambda x, y: x > y) expected_result = 8 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr7, 0, 5, 9, lambda x, y: x > y) + output = lower_bound(arr7, 9, end = 5, comp = lambda x, y: x > y) expected_result = 0 assert expected_result == output arr8 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr8, 0, 3, 6, lambda x, y: x > y) + output = lower_bound(arr8, 6, end = 3, comp = lambda x, y: x > y) expected_result = 1 assert expected_result == output From 9bfad38d01254c800ab092da6380161f5e019f02 Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Wed, 24 Mar 2021 02:00:22 +0530 Subject: [PATCH 07/11] minor refactoring --- pydatastructs/linear_data_structures/algorithms.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 651a1cec8..8e4e91349 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -817,8 +817,15 @@ def is_ordered(array, **kwargs): equal to is used for comparing two values. + Returns + ======= + + True if the specified ordering is present + from start to end (inclusive) otherwise False. + Examples ======== + >>> from pydatastructs import OneDimensionalArray, is_ordered >>> arr = OneDimensionalArray(int, [1, 2, 3, 4]) >>> is_ordered(arr) From 842b0d713e1494fb31874c705590f0408cdef834 Mon Sep 17 00:00:00 2001 From: Shivangi Nayak Date: Wed, 24 Mar 2021 20:29:52 +0530 Subject: [PATCH 08/11] updated docstring --- .../linear_data_structures/algorithms.py | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 8e4e91349..a913d5b0d 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -857,14 +857,19 @@ def upper_bound(array, value, **kwargs): The sorted array (sorted according to a custom comparator function) in which the upper bound has to be found - start: int + start: int, optional The staring index of the portion of the array in which the upper bound of a given value has to be looked for - end: int + end: int, optional The ending index of the portion of the array in which the upper bound of a given value has to be looked for + comp: boolean function, optional + A function that specifies the ordering of elements. By default, it takes two + parameters and returns True if 1st parameter is strictly smaller than + 2nd parameter + Returns ======= @@ -891,8 +896,6 @@ def upper_bound(array, value, **kwargs): start = kwargs.get('start', 0) end = kwargs.get('end', len(array)) comp = kwargs.get('comp', lambda x,y: x < y) - # if comp is None: - # comp = lambda a, b: (a < b) index = end inclusive_end = end - 1 if comp(value, array[start]): @@ -917,13 +920,19 @@ def lower_bound(array, value, **kwargs): The sorted array (sorted according to a custom comparator function) in which the lower bound has to be found - start: int + start: int, optional The staring index of the portion of the array in which the lower - bound of a given value has to be looked for + bound of a given value has to be looked for. Default value is set to 0. - end: int + end: int, optional The ending index of the portion of the array in which the lower - bound of a given value has to be looked for + bound of a given value has to be looked for. Default value is set to + end of array, i.e., len(arr) + + comp: boolean function, optional + A function that specifies the ordering of elements. By default, it takes two + parameters and returns True if 1st parameter is strictly smaller than + 2nd parameter Returns ======= @@ -951,8 +960,6 @@ def lower_bound(array, value, **kwargs): start = kwargs.get('start', 0) end = kwargs.get('end', len(array)) comp = kwargs.get('comp', lambda x, y: x < y) - # if comp is None: - # comp = lambda a, b: (a < b) index = end inclusive_end = end - 1 if not comp(array[start], value): From 25ea3cd39c0113dababb73f06776bb882647e14d Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Sat, 27 Mar 2021 15:35:07 +0530 Subject: [PATCH 09/11] polished --- .../linear_data_structures/algorithms.py | 98 +++++++++++-------- .../tests/test_algorithms.py | 30 +++--- 2 files changed, 71 insertions(+), 57 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index a913d5b0d..3a95b1abd 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -798,7 +798,7 @@ def is_ordered(array, **kwargs): Parameters ========== - array: Array + array: OneDimensionalArray The array which is to be checked for having specified ordering among its elements. start: int @@ -848,27 +848,32 @@ def is_ordered(array, **kwargs): def upper_bound(array, value, **kwargs): """ - Finds the index of the first occurence of an element greater than value according - to an order defined,in the given sorted OneDimensionalArray + Finds the index of the first occurence of an element greater than the given + value according to specified order, in the given sorted OneDimensionalArray. Parameters - ======== + ========== + array: OneDimensionalArray - The sorted array (sorted according to a custom comparator function) in which the - upper bound has to be found + The sorted array in which the upper bound has to be found. - start: int, optional + start: int The staring index of the portion of the array in which the upper bound - of a given value has to be looked for + of a given value has to be looked for. + Optional, by default 0 end: int, optional The ending index of the portion of the array in which the upper bound - of a given value has to be looked for + of a given value has to be looked for. + Optional, by default the index + of the last position filled. - comp: boolean function, optional - A function that specifies the ordering of elements. By default, it takes two - parameters and returns True if 1st parameter is strictly smaller than - 2nd parameter + comp: lambda/function + The comparator which is to be used + for specifying the desired ordering. + Optional, by default, less than or + equal to is used for comparing two + values. Returns ======= @@ -878,24 +883,26 @@ def upper_bound(array, value, **kwargs): Examples ======== + >>> from pydatastructs import upper_bound, OneDimensionalArray as ODA - >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> upperBound = upper_bound(arr, 5, start = 0, end = 4) - >>> upperBound + >>> arr1 = ODA(int, [4, 5, 5, 6, 7]) + >>> ub = upper_bound(arr1, 5, start=0, end=4) + >>> ub 3 - >>> arr = ODA(int, [7, 6, 5, 5, 4]) - >>> upperBound = upper_bound(arr, 5, comp = lambda x, y: x > y) - >>> upperBound + >>> arr2 = ODA(int, [7, 6, 5, 5, 4]) + >>> ub = upper_bound(arr2, 5, comp=lambda x, y: x > y) + >>> ub 4 Note ==== - The OneDimensionalArray must be sorted beforehand + The given OneDimensionalArray object must be sorted. + DynamicOneDimensionalArray objects may not work as expected. """ start = kwargs.get('start', 0) end = kwargs.get('end', len(array)) - comp = kwargs.get('comp', lambda x,y: x < y) + comp = kwargs.get('comp', lambda x, y: x < y) index = end inclusive_end = end - 1 if comp(value, array[start]): @@ -912,50 +919,57 @@ def upper_bound(array, value, **kwargs): def lower_bound(array, value, **kwargs): """ Finds the the index of the first occurence of an element which is not - less than value according to an order defined, in the given OneDimensionalArray + less than the given value according to specified order, + in the given sorted OneDimensionalArray Parameters - ======== + ========== + array: OneDimensionalArray - The sorted array (sorted according to a custom comparator function) - in which the lower bound has to be found + The sorted array in which the lower bound has to be found. - start: int, optional - The staring index of the portion of the array in which the lower - bound of a given value has to be looked for. Default value is set to 0. + start: int + The staring index of the portion of the array in which the upper bound + of a given value has to be looked for. + Optional, by default 0 end: int, optional - The ending index of the portion of the array in which the lower - bound of a given value has to be looked for. Default value is set to - end of array, i.e., len(arr) + The ending index of the portion of the array in which the upper bound + of a given value has to be looked for. + Optional, by default the index + of the last position filled. - comp: boolean function, optional - A function that specifies the ordering of elements. By default, it takes two - parameters and returns True if 1st parameter is strictly smaller than - 2nd parameter + comp: lambda/function + The comparator which is to be used + for specifying the desired ordering. + Optional, by default, less than or + equal to is used for comparing two + values. Returns ======= + output: int - Index of the lower bound of the given value in the given sorted OneDimensionalArray + Index of the lower bound of the given value in the given OneDimensionalArray Examples ======== >>> from pydatastructs import lower_bound, OneDimensionalArray as ODA - >>> arr = ODA(int, [4, 5, 5, 6, 7]) - >>> lowerBound = lower_bound(arr, 5, end = 4, comp = lambda x, y : x < y) - >>> lowerBound + >>> arr1 = ODA(int, [4, 5, 5, 6, 7]) + >>> lb = lower_bound(arr1, 5, end=4, comp=lambda x, y : x < y) + >>> lb 1 >>> arr = ODA(int, [7, 6, 5, 5, 4]) - >>> lowerBound = lower_bound(arr, 5, start = 0, comp = lambda x, y : x > y) - >>> lowerBound + >>> lb = lower_bound(arr, 5, start=0, comp=lambda x, y : x > y) + >>> lb 2 Note ==== - The OneDimensionalArray must be sorted beforehand + The given OneDimensionalArray object must be sorted. + DynamicOneDimensionalArray objects may not work as expected. """ start = kwargs.get('start', 0) end = kwargs.get('end', len(array)) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 0d5f4bed7..a0b98bb6a 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -148,7 +148,7 @@ def test_is_ordered(): expected_result = True arr3 = ODA(int, [0, -1, -2, -3, -4, 4]) - output = is_ordered(arr3, start = 1, end = 4, comp = lambda u, v: u > v) + output = is_ordered(arr3, start=1, end=4, comp=lambda u, v: u > v) assert output == expected_result expected_result = True @@ -165,37 +165,37 @@ def test_upper_bound(): assert expected_result == output arr2 = ODA(int, [4, 4, 5, 6]) - output = upper_bound(arr2, 4, end = 3) + output = upper_bound(arr2, 4, end=3) expected_result = 2 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = upper_bound(arr3, 5, start = 2, end = 4) + output = upper_bound(arr3, 5, start=2, end=4) expected_result = 2 assert expected_result == output arr4 = ODA(int, [3, 4, 4, 6]) - output = upper_bound(arr4, 5, start = 1, end = 3) + output = upper_bound(arr4, 5, start=1, end=3) expected_result = 3 assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr5, 6, comp = lambda x, y: x > y) + output = upper_bound(arr5, 6, comp=lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr6, 2, start = 2, comp = lambda x, y: x > y) + output = upper_bound(arr6, 2, start=2, comp=lambda x, y: x > y) expected_result = 8 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr7, 9, start = 3, end = 7, comp = lambda x, y: x > y) + output = upper_bound(arr7, 9, start=3, end=7, comp=lambda x, y: x > y) expected_result = 3 assert expected_result == output arr8 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = upper_bound(arr8, 6, end = 3, comp = lambda x, y: x > y) + output = upper_bound(arr8, 6, end=3, comp=lambda x, y: x > y) expected_result = 3 assert expected_result == output @@ -203,17 +203,17 @@ def test_upper_bound(): def test_lower_bound(): ODA = OneDimensionalArray arr1 = ODA(int, [3, 3, 3]) - output = lower_bound(arr1, 3, start = 1) + output = lower_bound(arr1, 3, start=1) expected_result = 1 assert expected_result == output arr2 = ODA(int, [4, 4, 4, 4, 5, 6]) - output = lower_bound(arr2, 5, end = 3) + output = lower_bound(arr2, 5, end=3) expected_result = 3 assert expected_result == output arr3 = ODA(int, [6, 6, 7, 8, 9]) - output = lower_bound(arr3, 5, end = 3) + output = lower_bound(arr3, 5, end=3) expected_result = 0 assert expected_result == output @@ -223,21 +223,21 @@ def test_lower_bound(): assert expected_result == output arr5 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr5, 5, comp = lambda x, y: x > y) + output = lower_bound(arr5, 5, comp=lambda x, y: x > y) expected_result = 5 assert expected_result == output arr6 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr6, 2, start = 4, comp = lambda x, y: x > y) + output = lower_bound(arr6, 2, start=4, comp=lambda x, y: x > y) expected_result = 8 assert expected_result == output arr7 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr7, 9, end = 5, comp = lambda x, y: x > y) + output = lower_bound(arr7, 9, end=5, comp=lambda x, y: x > y) expected_result = 0 assert expected_result == output arr8 = ODA(int, [7, 6, 6, 6, 6, 5, 4, 3]) - output = lower_bound(arr8, 6, end = 3, comp = lambda x, y: x > y) + output = lower_bound(arr8, 6, end=3, comp=lambda x, y: x > y) expected_result = 1 assert expected_result == output From 523344eac8a5efb03a1534447ed2bcc5236b4861 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Sat, 27 Mar 2021 18:47:52 +0530 Subject: [PATCH 10/11] Apply suggestions from code review --- pydatastructs/linear_data_structures/algorithms.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 3a95b1abd..2218a3599 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -849,13 +849,13 @@ def is_ordered(array, **kwargs): def upper_bound(array, value, **kwargs): """ Finds the index of the first occurence of an element greater than the given - value according to specified order, in the given sorted OneDimensionalArray. + value according to specified order, in the given OneDimensionalArray using a variation of binary search method. Parameters ========== array: OneDimensionalArray - The sorted array in which the upper bound has to be found. + The array in which the upper bound has to be found. start: int The staring index of the portion of the array in which the upper bound @@ -879,7 +879,7 @@ def upper_bound(array, value, **kwargs): ======= output: int - Index of the upper bound of the given value in the given sorted OneDimensionalArray + Index of the upper bound of the given value in the given OneDimensionalArray. Examples ======== @@ -897,7 +897,6 @@ def upper_bound(array, value, **kwargs): Note ==== - The given OneDimensionalArray object must be sorted. DynamicOneDimensionalArray objects may not work as expected. """ start = kwargs.get('start', 0) @@ -920,13 +919,13 @@ def lower_bound(array, value, **kwargs): """ Finds the the index of the first occurence of an element which is not less than the given value according to specified order, - in the given sorted OneDimensionalArray + in the given OneDimensionalArray using a variation of binary search method. Parameters ========== array: OneDimensionalArray - The sorted array in which the lower bound has to be found. + The array in which the lower bound has to be found. start: int The staring index of the portion of the array in which the upper bound @@ -968,7 +967,6 @@ def lower_bound(array, value, **kwargs): Note ==== - The given OneDimensionalArray object must be sorted. DynamicOneDimensionalArray objects may not work as expected. """ start = kwargs.get('start', 0) From c6768295a5c082bbbe3428b42477580bb844fcb9 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Sat, 27 Mar 2021 18:49:53 +0530 Subject: [PATCH 11/11] Apply suggestions from code review --- pydatastructs/linear_data_structures/algorithms.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 2218a3599..a82abbdc7 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -856,18 +856,15 @@ def upper_bound(array, value, **kwargs): array: OneDimensionalArray The array in which the upper bound has to be found. - start: int The staring index of the portion of the array in which the upper bound of a given value has to be looked for. Optional, by default 0 - end: int, optional The ending index of the portion of the array in which the upper bound of a given value has to be looked for. Optional, by default the index of the last position filled. - comp: lambda/function The comparator which is to be used for specifying the desired ordering. @@ -878,7 +875,7 @@ def upper_bound(array, value, **kwargs): Returns ======= - output: int + index: int Index of the upper bound of the given value in the given OneDimensionalArray. Examples @@ -926,18 +923,15 @@ def lower_bound(array, value, **kwargs): array: OneDimensionalArray The array in which the lower bound has to be found. - start: int The staring index of the portion of the array in which the upper bound of a given value has to be looked for. Optional, by default 0 - end: int, optional The ending index of the portion of the array in which the upper bound of a given value has to be looked for. Optional, by default the index of the last position filled. - comp: lambda/function The comparator which is to be used for specifying the desired ordering. @@ -948,7 +942,7 @@ def lower_bound(array, value, **kwargs): Returns ======= - output: int + index: int Index of the lower bound of the given value in the given OneDimensionalArray Examples