Source

metaljoe_codekata / kata2 / code_kata_2d.clj

Full commit
; http://codekata.pragprog.com/2007/01/kata_two_karate.html

(ns code-kata)

  
(defn
  #^{:test (fn []
			 (assert (= -1 (chop 3 []) ))
			 (assert (= -1 (chop 3 [1]) ))
			 (assert (=  0 (chop 1 [1]) ))

			 (assert (=  0 (chop 1 [1 3 5]) ))  ; failing
			 (assert (=  1 (chop 3 [1 3 5]) ))
			 (assert (=  2 (chop 5 [1 3 5]) ))  ; failing
			 (assert (= -1 (chop 0 [1 3 5]) ))
			 (assert (= -1 (chop 2 [1 3 5]) ))
			 (assert (= -1 (chop 4 [1 3 5]) ))
			 (assert (= -1 (chop 6 [1 3 5]) ))

			 (assert (=  0 (chop 1 [1 3 5 7]) )) ; failing
			 (assert (=  1 (chop 3 [1 3 5 7]) ))
			 (assert (=  2 (chop 5 [1 3 5 7]) ))
			 (assert (=  3 (chop 7 [1 3 5 7]) ))
			 (assert (= -1 (chop 0 [1 3 5 7]) ))
			 (assert (= -1 (chop 2 [1 3 5 7]) ))
			 (assert (= -1 (chop 4 [1 3 5 7]) ))
			 (assert (= -1 (chop 6 [1 3 5 7]) ))
			 (assert (= -1 (chop 8 [1 3 5 7]) )) ) }
  chop
  [item list]
  (def start        (atom 0))
  (def offset       (atom (quot (count list) 2)))
  (def current-item (atom nil))

  (loop [ position (+ @start @offset) ]
	(reset! current-item (get list position))
	(if (nil? @current-item)
	  -1
	  (if (= @current-item item)
		position
		(if (= @offset 0)
		  -1
		  (do
			(reset! start  position)
			(reset! offset (quot @offset 2))
			(if (< @current-item item)
			  (recur (+ position @offset))  ; go right
			  (recur (- position @offset))  ; go left
	  	    )
	      )
        )
      )
    )
  )
)

(test #'chop)