diff --git a/lib/search/binary_search.ex b/lib/search/binary_search.ex new file mode 100644 index 0000000..6b4eb0e --- /dev/null +++ b/lib/search/binary_search.ex @@ -0,0 +1,29 @@ +defmodule Algorithms.Search.BinarySearch do + @moduledoc """ + Performs a binary search on a sorted list and returns the index of the target element. + If the target is not found, it returns -1. + """ + def search(list, target) do + binary_search(list, target, 0, length(list) - 1) + end + + defp binary_search(_list, _target, low, high) when low > high do + -1 + end + + defp binary_search(list, target, low, high) do + mid = div(low + high, 2) + current = Enum.at(list, mid) + + cond do + current == target -> + mid + + current > target -> + binary_search(list, target, low, mid - 1) + + current < target -> + binary_search(list, target, mid + 1, high) + end + end +end diff --git a/test/search/binary_search_test.exs b/test/search/binary_search_test.exs new file mode 100644 index 0000000..d9ece51 --- /dev/null +++ b/test/search/binary_search_test.exs @@ -0,0 +1,43 @@ +defmodule Algorithms.Search.BinarySearchTest do + alias Algorithms.Search.BinarySearch + + use ExUnit.Case + + describe "search/2 - example test cases" do + test "finds element in the middle of the list" do + assert BinarySearch.search([1, 3, 5, 7, 9], 5) == 2 + end + + test "finds element at the beginning of the list" do + assert BinarySearch.search([1, 3, 5, 7, 9], 1) == 0 + end + + test "finds element at the end of the list" do + assert BinarySearch.search([1, 3, 5, 7, 9], 9) == 4 + end + + test "returns -1 when element is not in the list" do + assert BinarySearch.search([1, 3, 5, 7, 9], 4) == -1 + end + + test "works with an empty list" do + assert BinarySearch.search([], 1) == -1 + end + + test "works with a single-element list" do + assert BinarySearch.search([1], 1) == 0 + assert BinarySearch.search([1], 2) == -1 + end + + test "works with a large sorted list" do + list = Enum.to_list(1..1000) + assert BinarySearch.search(list, 500) == 499 + assert BinarySearch.search(list, 1001) == -1 + end + + test "handles duplicate elements" do + assert BinarySearch.search([1, 2, 2, 3, 4, 5, 5, 6], 2) in [1, 2] + assert BinarySearch.search([1, 2, 2, 3, 4, 5, 5, 6], 5) in [5, 6] + end + end +end