|
11 | 11 | from __future__ import annotations |
12 | 12 |
|
13 | 13 |
|
14 | | -def binary_search(a_list: list[int], item: int) -> bool: |
| 14 | +def binary_search(a_list: list[int], item: int) -> int: |
15 | 15 | """ |
| 16 | + Returns the leftmost index of `item` in `a_list` if found, |
| 17 | + otherwise returns -1. |
| 18 | +
|
16 | 19 | >>> test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42] |
17 | 20 | >>> binary_search(test_list, 3) |
18 | | - False |
| 21 | + -1 |
19 | 22 | >>> binary_search(test_list, 13) |
20 | | - True |
| 23 | + 4 |
21 | 24 | >>> binary_search([4, 4, 5, 6, 7], 4) |
22 | | - True |
| 25 | + 0 |
23 | 26 | >>> binary_search([4, 4, 5, 6, 7], -10) |
24 | | - False |
| 27 | + -1 |
25 | 28 | >>> binary_search([-18, 2], -18) |
26 | | - True |
| 29 | + 0 |
27 | 30 | >>> binary_search([5], 5) |
28 | | - True |
| 31 | + 0 |
29 | 32 | >>> binary_search(['a', 'c', 'd'], 'c') |
30 | | - True |
| 33 | + 1 |
31 | 34 | >>> binary_search(['a', 'c', 'd'], 'f') |
32 | | - False |
| 35 | + -1 |
33 | 36 | >>> binary_search([], 1) |
34 | | - False |
| 37 | + -1 |
35 | 38 | >>> binary_search([-.1, .1 , .8], .1) |
36 | | - True |
| 39 | + 1 |
37 | 40 | >>> binary_search(range(-5000, 5000, 10), 80) |
38 | | - True |
| 41 | + 508 |
39 | 42 | >>> binary_search(range(-5000, 5000, 10), 1255) |
40 | | - False |
| 43 | + -1 |
41 | 44 | >>> binary_search(range(0, 10000, 5), 2) |
42 | | - False |
| 45 | + -1 |
43 | 46 | """ |
44 | | - if len(a_list) == 0: |
45 | | - return False |
46 | | - midpoint = len(a_list) // 2 |
47 | | - if a_list[midpoint] == item: |
48 | | - return True |
49 | | - if item < a_list[midpoint]: |
50 | | - return binary_search(a_list[:midpoint], item) |
51 | | - else: |
52 | | - return binary_search(a_list[midpoint + 1 :], item) |
| 47 | + low, high = 0, len(a_list) - 1 |
| 48 | + result = -1 |
| 49 | + |
| 50 | + while low <= high: |
| 51 | + mid = (low + high) // 2 |
| 52 | + if a_list[mid] == item: |
| 53 | + result = mid |
| 54 | + high = mid - 1 # keep searching left for duplicates |
| 55 | + elif item < a_list[mid]: |
| 56 | + high = mid - 1 |
| 57 | + else: |
| 58 | + low = mid + 1 |
| 59 | + |
| 60 | + return result |
53 | 61 |
|
54 | 62 |
|
55 | 63 | if __name__ == "__main__": |
56 | 64 | user_input = input("Enter numbers separated by comma:\n").strip() |
57 | 65 | sequence = [int(item.strip()) for item in user_input.split(",")] |
58 | 66 | target = int(input("Enter the number to be found in the list:\n").strip()) |
59 | | - not_str = "" if binary_search(sequence, target) else "not " |
60 | | - print(f"{target} was {not_str}found in {sequence}") |
| 67 | + index = binary_search(sequence, target) |
| 68 | + if index != -1: |
| 69 | + print(f"{target} found at index {index} in {sequence}") |
| 70 | + else: |
| 71 | + print(f"{target} was not found in {sequence}") |
0 commit comments