Dave Snowdon wrote:

> ; 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)))

I think the main thing that's confusing here is that you're messing
with offsets and split collections at once. At least is was confusing
to me. :)

I think for binary search (which implies random lookup is ~ O(n)
anyway) it's clearer if you stick to offsets.

A few remarks regarding style:

You don't need letfn; personally I think it's clearer to use either
two separate functions or - in this case - specialize on the
arguments.

If you define assert_equal as a function, you won't get any good
feedback if the assert fails. Use a macro instead.

Here's what I made:

(defn chop
  ([val coll]
     (chop val coll 0 (count coll)))
  ([val coll left right] ; range to test is left ... right - 1, which
makes the code a bit cleaner
     (if (< left right) ; are we still in a valid range?
       (let [halve (int (/ (- right left) 2))
             index (+ left halve)
             found-value (coll index)]
         (cond
          (= val found-value) index
          (> val found-value) (recur val coll (inc index) right)
          (< val found-value) (recur val coll left index)))
       -1))) ; not found

(defmacro assert_equal
  [v1 v2]
  `(assert (= ~v1 ~v2)))

Note that all of this is pretty low-level but I think it looks kinda
nice and readable.

-- 
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