Skip to content

Commit

Permalink
Binary search: Sync metadata docs, implement tests, update example so…
Browse files Browse the repository at this point in the history
…lution (#643)

* sync docs

* sync metadata

* implement tests

* update example solution (no explicit recursion, passes new tests)
  • Loading branch information
tasxatzial authored Jun 5, 2024
1 parent aa65869 commit 9e50cee
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 50 deletions.
2 changes: 1 addition & 1 deletion exercises/practice/binary-search/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Binary search only works when a list has been sorted.

The algorithm looks like this:

- Find the middle element of a *sorted* list and compare it with the item we're looking for.
- Find the middle element of a _sorted_ list and compare it with the item we're looking for.
- If the middle element is our item, then we're done!
- If the middle element is greater than our item, we can eliminate that element and all the elements **after** it.
- If the middle element is less than our item, we can eliminate that element and all the elements **before** it.
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/binary-search/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@
},
"blurb": "Implement a binary search algorithm.",
"source": "Wikipedia",
"source_url": "http://en.wikipedia.org/wiki/Binary_search_algorithm"
"source_url": "https://en.wikipedia.org/wiki/Binary_search_algorithm"
}
23 changes: 12 additions & 11 deletions exercises/practice/binary-search/.meta/src/example.clj
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
(ns binary-search)

(defn middle [alist]
(-> alist (count) (quot 2)))

(defn search-for
[elem alist]
(let [middle (middle alist)
cur-elem (nth alist middle)]
(cond
(= cur-elem elem) middle
(or (= middle (count alist)) (zero? middle)) (throw (Exception. (format "%s not found in list" elem)))
(< cur-elem elem) (+ middle (search-for elem (drop middle alist)))
(> cur-elem elem) (search-for elem (take middle alist)))))
[n coll]
(let [coll (vec coll)]
(loop [low-idx 0
high-idx (dec (count coll))]
(if (> low-idx high-idx)
(throw (Exception. "not found"))
(let [mid-index (quot (+ high-idx low-idx) 2)
mid-item (get coll mid-index)]
(cond
(= n mid-item) mid-index
(> mid-item n) (recur low-idx (dec mid-index))
:else (recur (inc mid-index) high-idx)))))))
86 changes: 49 additions & 37 deletions exercises/practice/binary-search/test/binary_search_test.clj
Original file line number Diff line number Diff line change
@@ -1,40 +1,52 @@
(ns binary-search-test
(:require [clojure.test :refer [deftest is]]
(:require [clojure.test :refer [deftest is testing]]
binary-search))

(def short-vector [1, 3, 4, 6, 8, 9, 11])

(def large-vector [1, 3, 5, 8, 13, 21, 34, 55, 89])

(def even-length-vector [1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377])

(deftest it-finds-position-of-middle-item
(is (= 3 (binary-search/middle short-vector))))

(deftest searches-a-singleton
(is (= 0 (binary-search/search-for 4 [4]))))

(deftest it-finds-position-of-search-data
(is (= 5 (binary-search/search-for 9 short-vector))))

(deftest it-finds-position-in-a-larger-list
(is (= 1 (binary-search/search-for 3 large-vector))))

(deftest it-finds-position-in-a-larger-list-again
(is (= 7 (binary-search/search-for 55 large-vector))))

(deftest it-finds-correct-position-in-a-list-with-an-even-number-of-elements
(is (= 5 (binary-search/search-for 21 even-length-vector))))

(deftest it-finds-correct-position-in-a-list-with-an-even-number-of-elements-again
(is (= 6 (binary-search/search-for 34 even-length-vector))))

(deftest it-works-on-lists
(is (= 7 (binary-search/search-for 7 (range 10)))))

(deftest it-works-on-lists-again
(is (= 4 (binary-search/search-for 3 '(-3 -2 0 1 3 4)))))

(deftest throws-exception-when-element-not-found
(is (thrown-with-msg? Throwable #"not found"
(binary-search/search-for 20 short-vector))))
(deftest finds-value-in-array-with-one-element
(testing "Finds a value in an array with one element"
(is (= 0 (binary-search/search-for 6 [6])))))

(deftest finds-value-in-middle-of-array
(testing "Finds a value in the middle of an array"
(is (= 3 (binary-search/search-for 6 [1, 3, 4, 6, 8, 9, 11])))))

(deftest finds-value-at-beginning-of-array
(testing "Finds a value at the beginning of an array"
(is (= 0 (binary-search/search-for 1 [1, 3, 4, 6, 8, 9, 11])))))

(deftest finds-value-at-end-of-array
(testing "Finds a value at the end of an array"
(is (= 6 (binary-search/search-for 11 [1, 3, 4, 6, 8, 9, 11])))))

(deftest finds-value-in-array-of-odd-length
(testing "Finds a value in an array of odd length"
(is (= 9 (binary-search/search-for 144 [1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634])))))

(deftest finds-value-in-array-of-even-length
(testing "Finds a value in an array of even length"
(is (= 5 (binary-search/search-for 21 [1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377])))))

(deftest identifies-that-value-is-not-in-array
(testing "Identifies that a value is not included in the array"
(is (thrown-with-msg? Throwable #"not found"
(binary-search/search-for 7 [1, 3, 4, 6, 8, 9, 11])))))

(deftest value-smaller-than-arrays-smallest-value-not-found
(testing "A value smaller than the array's smallest value is not found"
(is (thrown-with-msg? Throwable #"not found"
(binary-search/search-for 0 [1, 3, 4, 6, 8, 9, 11])))))

(deftest value-larger-than-arrays-largest-value-not-found
(testing "A value larger than the array's largest value is not found"
(is (thrown-with-msg? Throwable #"not found"
(binary-search/search-for 13 [1, 3, 4, 6, 8, 9, 11])))))

(deftest nothing-found-in-empty-array
(testing "Nothing is found in an empty array"
(is (thrown-with-msg? Throwable #"not found"
(binary-search/search-for 1 [])))))

(deftest nothing-found-when-left-and-right-bounds-cross
(testing "Nothing is found when the left and right bounds cross"
(is (thrown-with-msg? Throwable #"not found"
(binary-search/search-for 0 [1, 2])))))

0 comments on commit 9e50cee

Please sign in to comment.