Hi folks
I've just started teaching myself clojure and for lack of a "real" project
to use it on I've been using the "code kata" on pragprog.com as example
problems to solve.

I've implemented the binary search as described here:
http://codekata.pragprog.com/2007/01/kata_two_karate.html however I'm not at
all happy with the results. From what I've seen of idiomatic clojure posted
on this list there seems to be too much (ugly) code in my solution and I'm
sure there must be a more concise implementation but I can't see it.

Now I have no illusions that this is efficient and I don't imagine you'd
really use a binary search to locate items in real clojure programs so
please don't just point me at a library function and tell me to use that.
What I'm interested in is how I would re-implement "chop" in more idiomatic
clojure and would be very grateful for any pointers you can give me.

thanks

Dave

; helper function that splits a collection into halves
(defn halve [coll]
 (let [len (count coll), hl (- len (/ len 2))]
    [(take hl coll) (drop hl coll)]
    )
  )

; takes a value and an ordered sequence and returns the index of the value
or -1
(defn chop [val coll]
  (letfn [(chop2 [ofst val coll]
  (cond (empty? coll) -1
        (= 1 (count coll)) (if (= val (first coll)) ofst -1)
:else (let [[fh sh] (halve coll), sel (first sh)]
    (cond (= val sel) (+ ofst (count fh))
                  (< val sel) (recur ofst val fh)
                  :else (recur (+ ofst (count fh)) val sh)))))]
    (chop2 0  val coll)))

(defn assert_equal [v1 v2] (assert (= v1 v2)))

(defn test_chop []
    (assert_equal -1, (chop 3, []))
    (assert_equal -1, (chop 3, [1]))
    (assert_equal 0,  (chop 1, [1]))

    (assert_equal 0,  (chop 1, [1, 3, 5]))
    (assert_equal 1,  (chop 3, [1, 3, 5]))
    (assert_equal 2,  (chop 5, [1, 3, 5]))
    (assert_equal -1, (chop 0, [1, 3, 5]))
    (assert_equal -1, (chop 2, [1, 3, 5]))
    (assert_equal -1, (chop 4, [1, 3, 5]))
    (assert_equal -1, (chop 6, [1, 3, 5]))

    (assert_equal 0,  (chop 1, [1, 3, 5, 7]))
    (assert_equal 1,  (chop 3, [1, 3, 5, 7]))
    (assert_equal 2,  (chop 5, [1, 3, 5, 7]))
    (assert_equal 3,  (chop 7, [1, 3, 5, 7]))
    (assert_equal -1, (chop 0, [1, 3, 5, 7]))
    (assert_equal -1, (chop 2, [1, 3, 5, 7]))
    (assert_equal -1, (chop 4, [1, 3, 5, 7]))
    (assert_equal -1, (chop 6, [1, 3, 5, 7]))
    (assert_equal -1, (chop 8, [1, 3, 5, 7]))
)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to