diff --git a/src/binary_search.py b/src/binary_search.py new file mode 100644 index 00000000..25115250 --- /dev/null +++ b/src/binary_search.py @@ -0,0 +1,43 @@ +def binary_search(arr, target): + """ + Perform binary search on a sorted array to find the target element. + + Args: + arr (list): A sorted list of comparable elements. + target: The element to search for in the array. + + Returns: + int: The index of the target element if found, -1 otherwise. + + Raises: + TypeError: If the input is not a list. + ValueError: If the input list is not sorted. + """ + # Validate input + if not isinstance(arr, list): + raise TypeError("Input must be a list") + + # Check if the list is sorted + if not all(arr[i] <= arr[i+1] for i in range(len(arr)-1)): + raise ValueError("Input list must be sorted in ascending order") + + # Binary search implementation + left, right = 0, len(arr) - 1 + + while left <= right: + mid = (left + right) // 2 + + # If target is found, return its index + if arr[mid] == target: + return mid + + # If target is greater, ignore left half + elif arr[mid] < target: + left = mid + 1 + + # If target is smaller, ignore right half + else: + right = mid - 1 + + # Target not found + return -1 \ No newline at end of file diff --git a/tests/test_binary_search.py b/tests/test_binary_search.py new file mode 100644 index 00000000..88b3e86d --- /dev/null +++ b/tests/test_binary_search.py @@ -0,0 +1,39 @@ +import pytest +from src.binary_search import binary_search + +def test_binary_search_basic(): + """Test basic binary search functionality.""" + arr = [1, 3, 5, 7, 9, 11, 13] + assert binary_search(arr, 7) == 3 # 7 is at index 3 + assert binary_search(arr, 13) == 6 # Last element + assert binary_search(arr, 1) == 0 # First element + +def test_binary_search_not_found(): + """Test when target is not in the array.""" + arr = [1, 3, 5, 7, 9, 11, 13] + assert binary_search(arr, 4) == -1 + assert binary_search(arr, 0) == -1 + assert binary_search(arr, 14) == -1 + +def test_binary_search_edge_cases(): + """Test edge cases like empty list and single-element list.""" + assert binary_search([], 5) == -1 + assert binary_search([1], 1) == 0 + assert binary_search([1], 2) == -1 + +def test_binary_search_invalid_inputs(): + """Test error handling for invalid inputs.""" + # Not a list + with pytest.raises(TypeError, match="Input must be a list"): + binary_search("not a list", 5) + + # Unsorted list + with pytest.raises(ValueError, match="Input list must be sorted in ascending order"): + binary_search([5, 3, 1], 3) + +def test_binary_search_duplicate_values(): + """Test handling of duplicate values.""" + arr = [1, 2, 2, 3, 3, 3, 4, 5] + # Returns the index of the first occurrence of the target + assert binary_search(arr, 3) in [3, 4, 5] + assert binary_search(arr, 2) in [1, 2] \ No newline at end of file