From 37afac6f89527bf09a8086a3e374789b83d28faf Mon Sep 17 00:00:00 2001 From: Maksym Konotop Date: Sun, 19 Jul 2026 18:53:36 +0300 Subject: [PATCH 1/2] Improve simple binary search according to the standard binary search definition --- searches/simple_binary_search.py | 61 +++++++++++++++---------- test.patch | Bin 0 -> 2028 bytes test.sh | 18 ++++++++ tests/test_binary_search_duplicates.py | 8 ++++ 4 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 test.patch create mode 100644 test.sh create mode 100644 tests/test_binary_search_duplicates.py diff --git a/searches/simple_binary_search.py b/searches/simple_binary_search.py index 00e83ff9e4a3..895434d7473d 100644 --- a/searches/simple_binary_search.py +++ b/searches/simple_binary_search.py @@ -11,50 +11,61 @@ from __future__ import annotations -def binary_search(a_list: list[int], item: int) -> bool: +def binary_search(a_list: list[int], item: int) -> int: """ + Returns the leftmost index of `item` in `a_list` if found, + otherwise returns -1. + >>> test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42] >>> binary_search(test_list, 3) - False + -1 >>> binary_search(test_list, 13) - True + 4 >>> binary_search([4, 4, 5, 6, 7], 4) - True + 0 >>> binary_search([4, 4, 5, 6, 7], -10) - False + -1 >>> binary_search([-18, 2], -18) - True + 0 >>> binary_search([5], 5) - True + 0 >>> binary_search(['a', 'c', 'd'], 'c') - True + 1 >>> binary_search(['a', 'c', 'd'], 'f') - False + -1 >>> binary_search([], 1) - False + -1 >>> binary_search([-.1, .1 , .8], .1) - True + 1 >>> binary_search(range(-5000, 5000, 10), 80) - True + 508 >>> binary_search(range(-5000, 5000, 10), 1255) - False + -1 >>> binary_search(range(0, 10000, 5), 2) - False + -1 """ - if len(a_list) == 0: - return False - midpoint = len(a_list) // 2 - if a_list[midpoint] == item: - return True - if item < a_list[midpoint]: - return binary_search(a_list[:midpoint], item) - else: - return binary_search(a_list[midpoint + 1 :], item) + low, high = 0, len(a_list) - 1 + result = -1 + + while low <= high: + mid = (low + high) // 2 + if a_list[mid] == item: + result = mid + high = mid - 1 # keep searching left for duplicates + elif item < a_list[mid]: + high = mid - 1 + else: + low = mid + 1 + + return result if __name__ == "__main__": user_input = input("Enter numbers separated by comma:\n").strip() sequence = [int(item.strip()) for item in user_input.split(",")] target = int(input("Enter the number to be found in the list:\n").strip()) - not_str = "" if binary_search(sequence, target) else "not " - print(f"{target} was {not_str}found in {sequence}") + index = binary_search(sequence, target) + if index != -1: + print(f"{target} found at index {index} in {sequence}") + else: + print(f"{target} was not found in {sequence}") diff --git a/test.patch b/test.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d55a363ca84be9b05cb6979b597eba4d7e15aa6 GIT binary patch literal 2028 zcmb`H-EI>x5QXO&iFYsop_Fu!hLnO*74?E%0uKNv+HA6=A|z3klvWk54*ib3ZZ>HU zZCP1sdp$osXFM~1evjCFpm&?ISXmOZs6cwNGB!8-IPJD{A}x%ZrU{z13kT=7ZJpRvx- zo^zHHG4T&t8CZolMK&+bg5QigEHDFST1egS!kb;Zv$eu1jPhY84LrGwr92CE-vd>Ufhbq*!vTkhG+Z@mNRlz z++(ix*{@>ktm&hom(Bdmde0bVhxLO0$XYM*)}E8S>$pN(l`Wf+6=GFb${n)&jOGU) z_25~|wNo|9i!xF;X1-cuy~*<5HC&L5@hu-3_4O*N!=tbVuJ!Z}^_w1FMui{n$^ZTP zM_tUecc1m%qi(3)d$+eyf6dWV)~a5&)ku^4?{8$H`hz;e0vo-e@@iYnHSLq{kjmIy zG^=yZzLaM>NRAi|T}8N6&iCVz`X0WGK|%G^!9l%V7{eUUckvw2@BIgQbr8irXH^#+ U)r2`jJjQyzf;K6m{qQbv4OAL1D*ylh literal 0 HcmV?d00001 diff --git a/test.sh b/test.sh new file mode 100644 index 000000000000..23bcf5475b8d --- /dev/null +++ b/test.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -uo pipefail +cd /app + +MODE="${1:-new}" + +case "$MODE" in + base) + pytest tests # run existing repo tests + ;; + new) + pytest tests/test_binary_search_duplicates.py + ;; + *) + echo "unknown mode: $MODE (expected base or new)" >&2 + exit 2 + ;; +esac \ No newline at end of file diff --git a/tests/test_binary_search_duplicates.py b/tests/test_binary_search_duplicates.py new file mode 100644 index 000000000000..1030c868cf2f --- /dev/null +++ b/tests/test_binary_search_duplicates.py @@ -0,0 +1,8 @@ +def test_binary_search_leftmost_duplicate(): + assert binary_search([1, 2, 2, 2, 3], 2) == 1 + +def test_binary_search_all_duplicates(): + assert binary_search([1, 1, 1, 1], 1) == 0 + +def test_binary_search_not_found(): + assert binary_search([1, 2, 3], 4) == -1 \ No newline at end of file From 40778759a094dbb820311075da39acf39d4f41eb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 19 Jul 2026 15:58:29 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_binary_search_duplicates.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_binary_search_duplicates.py b/tests/test_binary_search_duplicates.py index 1030c868cf2f..19892acf2c32 100644 --- a/tests/test_binary_search_duplicates.py +++ b/tests/test_binary_search_duplicates.py @@ -1,8 +1,10 @@ def test_binary_search_leftmost_duplicate(): assert binary_search([1, 2, 2, 2, 3], 2) == 1 + def test_binary_search_all_duplicates(): assert binary_search([1, 1, 1, 1], 1) == 0 + def test_binary_search_not_found(): - assert binary_search([1, 2, 3], 4) == -1 \ No newline at end of file + assert binary_search([1, 2, 3], 4) == -1