-
-
Notifications
You must be signed in to change notification settings - Fork 46.9k
Add type hints and tests. #2461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
010ff84
d953a02
e37a1dc
ca04b30
4c2877d
618db89
463a797
17eaff3
8c94201
cff60b9
bb58c55
a3df50a
efdc76f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,52 +6,131 @@ | |
Time Complexity : O(log3 N) | ||
Space Complexity : O(1) | ||
""" | ||
import sys | ||
from typing import List | ||
|
||
# This is the precision for this function which can be altered. | ||
# It is recommended for users to keep this number greater than or equal to 10. | ||
precision = 10 | ||
|
||
|
||
# This is the linear search that will occur after the search space has become smaller. | ||
def lin_search(left, right, A, target): | ||
for i in range(left, right + 1): | ||
def lin_search(left: int, right: int, A: List[int], target: int) -> int: | ||
"""Perform linear search in list. Returns -1 if element is not found. | ||
|
||
Parameters | ||
---------- | ||
left : int | ||
left index bound. | ||
right : int | ||
right index bound. | ||
A : List[int] | ||
List of elements to be searched on | ||
target : int | ||
Element that is searched | ||
|
||
Returns | ||
------- | ||
int | ||
index of element that is looked for. | ||
|
||
Examples | ||
-------- | ||
>>> print(lin_search(0, 4, [4, 5, 6, 7], 7)) | ||
3 | ||
>>> print(lin_search(0, 3, [4, 5, 6, 7], 7)) | ||
-1 | ||
>>> print(lin_search(0, 2, [-18, 2], -18)) | ||
0 | ||
>>> print(lin_search(0, 1, [5], 5)) | ||
0 | ||
>>> print(lin_search(0, 3, ['a', 'c', 'd'], 'c')) | ||
1 | ||
>>> print(lin_search(0, 3, [.1, .4 , -.1], .1)) | ||
0 | ||
>>> print(lin_search(0, 3, [.1, .4 , -.1], -.1)) | ||
2 | ||
""" | ||
for i in range(left, right): | ||
if A[i] == target: | ||
return i | ||
|
||
|
||
# This is the iterative method of the ternary search algorithm. | ||
def ite_ternary_search(A, target): | ||
return -1 | ||
|
||
|
||
def ite_ternary_search(A: List[int], target: int) -> int: | ||
"""Iterative method of the ternary search algorithm. | ||
>>> test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42] | ||
>>> print(ite_ternary_search(test_list, 3)) | ||
-1 | ||
>>> print(ite_ternary_search(test_list, 13)) | ||
4 | ||
>>> print(ite_ternary_search([4, 5, 6, 7], 4)) | ||
0 | ||
>>> print(ite_ternary_search([4, 5, 6, 7], -10)) | ||
-1 | ||
>>> print(ite_ternary_search([-18, 2], -18)) | ||
0 | ||
>>> print(ite_ternary_search([5], 5)) | ||
0 | ||
>>> print(ite_ternary_search(['a', 'c', 'd'], 'c')) | ||
1 | ||
>>> print(ite_ternary_search(['a', 'c', 'd'], 'f')) | ||
-1 | ||
>>> print(ite_ternary_search([], 1)) | ||
-1 | ||
>>> print(ite_ternary_search([.1, .4 , -.1], .1)) | ||
0 | ||
""" | ||
left = 0 | ||
right = len(A) - 1 | ||
while True: | ||
if left < right: | ||
|
||
if right - left < precision: | ||
return lin_search(left, right, A, target) | ||
right = len(A) | ||
while left <= right: | ||
if right - left < precision: | ||
return lin_search(left, right, A, target) | ||
|
||
oneThird = (left + right) / 3 + 1 | ||
twoThird = 2 * (left + right) / 3 + 1 | ||
oneThird = (left + right) / 3 + 1 | ||
twoThird = 2 * (left + right) / 3 + 1 | ||
|
||
if A[oneThird] == target: | ||
return oneThird | ||
elif A[twoThird] == target: | ||
return twoThird | ||
if A[oneThird] == target: | ||
return oneThird | ||
elif A[twoThird] == target: | ||
return twoThird | ||
|
||
elif target < A[oneThird]: | ||
right = oneThird - 1 | ||
elif A[twoThird] < target: | ||
left = twoThird + 1 | ||
elif target < A[oneThird]: | ||
right = oneThird - 1 | ||
elif A[twoThird] < target: | ||
left = twoThird + 1 | ||
|
||
else: | ||
left = oneThird + 1 | ||
right = twoThird - 1 | ||
else: | ||
return None | ||
|
||
|
||
# This is the recursive method of the ternary search algorithm. | ||
def rec_ternary_search(left, right, A, target): | ||
left = oneThird + 1 | ||
right = twoThird - 1 | ||
else: | ||
return -1 | ||
|
||
|
||
def rec_ternary_search(left: int, right: int, A: List[int], target: int) -> int: | ||
"""Recursive method of the ternary search algorithm. | ||
|
||
>>> test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42] | ||
>>> print(rec_ternary_search(0, len(test_list), test_list, 3)) | ||
-1 | ||
>>> print(rec_ternary_search(4, len(test_list), test_list, 42)) | ||
8 | ||
>>> print(rec_ternary_search(0, 2, [4, 5, 6, 7], 4)) | ||
0 | ||
>>> print(rec_ternary_search(0, 3, [4, 5, 6, 7], -10)) | ||
-1 | ||
>>> print(rec_ternary_search(0, 1, [-18, 2], -18)) | ||
0 | ||
>>> print(rec_ternary_search(0, 1, [5], 5)) | ||
0 | ||
>>> print(rec_ternary_search(0, 2, ['a', 'c', 'd'], 'c')) | ||
1 | ||
>>> print(rec_ternary_search(0, 2, ['a', 'c', 'd'], 'f')) | ||
-1 | ||
>>> print(rec_ternary_search(0, 0, [], 1)) | ||
-1 | ||
>>> print(rec_ternary_search(0, 3, [.1, .4 , -.1], .1)) | ||
0 | ||
""" | ||
if left < right: | ||
|
||
if right - left < precision: | ||
|
@@ -69,35 +148,28 @@ def rec_ternary_search(left, right, A, target): | |
return rec_ternary_search(left, oneThird - 1, A, target) | ||
elif A[twoThird] < target: | ||
return rec_ternary_search(twoThird + 1, right, A, target) | ||
|
||
else: | ||
return rec_ternary_search(oneThird + 1, twoThird - 1, A, target) | ||
else: | ||
return None | ||
return -1 | ||
|
||
|
||
# This function is to check if the array is sorted. | ||
def __assert_sorted(collection): | ||
if collection != sorted(collection): | ||
raise ValueError("Collection must be sorted") | ||
raise ValueError("Collection is not sorted.") | ||
return True | ||
|
||
|
||
if __name__ == "__main__": | ||
user_input = input("Enter numbers separated by coma:\n").strip() | ||
collection = [int(item) for item in user_input.split(",")] | ||
|
||
try: | ||
__assert_sorted(collection) | ||
except ValueError: | ||
sys.exit("Sequence must be sorted to apply the ternary search") | ||
|
||
target_input = input("Enter a single number to be found in the list:\n") | ||
target = int(target_input) | ||
user_input = input("Enter numbers separated by comma:\n").strip() | ||
collection = [int(item.strip()) for item in user_input.split(",")] | ||
__assert_sorted(collection) | ||
target = int(input("Enter the number to be found in the list:\n").strip()) | ||
result1 = ite_ternary_search(collection, target) | ||
result2 = rec_ternary_search(0, len(collection) - 1, collection, target) | ||
|
||
if result2 is not None: | ||
if result2 != -1: | ||
print(f"Iterative search: {target} found at positions: {result1}") | ||
print(f"Recursive search: {target} found at positions: {result2}") | ||
Comment on lines
167
to
168
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this provide the right answer if the user inputs an out-of-order list? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does not, I think it is better to return to the assert_sorted logic. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK but let's do it inline. We don't need a separate function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess my error could be avoided by testing that part of the code, however the use of inputs make it hard to test. Do you know any way that the main could be tested ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. def perform_searches(collection: List[int], target: int) -> None:
# put lines 159, 160, and 162-168 under this function and
# then you can test `perform_searches()` all day long. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I guess thats the same than testing each one of the two searches functions. |
||
else: | ||
|
Uh oh!
There was an error while loading. Please reload this page.