Repository: exercism/clojure
Pull request #643 (2024-06-05 13:21:37)

Binary search: Sync metadata docs, implement tests, update example solution
As mentioned here

http://forum.exercism.org/t/48in24-exercise-07-02-binary-search/11462/6

@ErikSchierboom 

github-actions[bot]: Hello. Thanks for opening a PR on Exercism 🙂

We ask that all changes to Exercism are discussed on our Community Forum before being opened on GitHub. To enforce this, we automatically close all PRs that are submitted. That doesn't mean your PR is rejected but that we want the initial discussion about it to happen on our forum where a wide range of key contributors across the Exercism ecosystem can weigh in.

You can use [this link](https://forum.exercism.org/new-topic?title=Binary%20search:%20Sync%20metadata%20docs,%20implement%20tests,%20update%20example%20solution&body=As%20mentioned%20here%0D%0A%0D%0Ahttp://forum.exercism.org/t/48in24-exercise-07-02-binary-search/11462/6%0D%0A%0D%0A@ErikSchierboom%20&category=clojure ) to copy this into a new topic on the forum. If we decide the PR is appropriate, we'll reopen it and continue with it, so please don't delete your local branch.

If you're interested in learning more about this auto-responder, please read [this blog post](https://exercism.org/blog/contribution-guidelines-nov-2023).

---

_Note: If this PR has been pre-approved, please link back to this PR on the forum thread and a maintainer or staff member will reopen it._
github-actions[bot]: This PR touches files which potentially affect the outcome of the tests of an exercise. This will cause all students' solutions to affected exercises to be re-tested.

If this PR does **not** affect the result of the test (or, for example, adds an edge case that is not worth rerunning all tests for), **please add the following to the merge-commit message** which will stops student's tests from re-running. Please copy-paste to avoid typos.
```
[no important files changed]
```

 For more information, refer to the [documentation](https://exercism.org/docs/building/tracks#h-avoiding-triggering-unnecessary-test-runs). If you are unsure whether to add the message or not, please ping `@exercism/maintainers-admin` in a comment. Thank you!

Patch:
diff --git a/exercises/practice/binary-search/.docs/instructions.md b/exercises/practice/binary-search/.docs/instructions.md
index aa1946c..12f4358 100644
--- a/exercises/practice/binary-search/.docs/instructions.md
+++ b/exercises/practice/binary-search/.docs/instructions.md
@@ -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.
diff --git a/exercises/practice/binary-search/.meta/config.json b/exercises/practice/binary-search/.meta/config.json
index 74b15a0..e2fe40d 100644
--- a/exercises/practice/binary-search/.meta/config.json
+++ b/exercises/practice/binary-search/.meta/config.json
@@ -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"
 }
diff --git a/exercises/practice/binary-search/.meta/src/example.clj b/exercises/practice/binary-search/.meta/src/example.clj
index 9ea77cf..416b0da 100644
--- a/exercises/practice/binary-search/.meta/src/example.clj
+++ b/exercises/practice/binary-search/.meta/src/example.clj
@@ -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)))))))


Test patch:
diff --git a/exercises/practice/binary-search/test/binary_search_test.clj b/exercises/practice/binary-search/test/binary_search_test.clj
index 00efed5..60f8464 100644
--- a/exercises/practice/binary-search/test/binary_search_test.clj
+++ b/exercises/practice/binary-search/test/binary_search_test.clj
@@ -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])))))