Next round of 4clojure.com solutions

After the seventh round, five more 4clojure.com solutions:

;;; Problem 60 - Sequence Reduction
(deftest test-problem-60
  (let [v1 (fn fred
             ([f [p1 & ps]] (fred f p1 ps))
             ([f p1 [p2 & ps]]
              (cons p1
                    (when p2
                      (lazy-seq (fred f (f p1 p2) ps))))))
        __ v1]
    (is (= (take 5 (__ + (range))) [0 1 3 6 10]))
    (is (= (__ conj [1] [2 3 4]) [[1] [1 2] [1 2 3] [1 2 3 4]]))
    (is (= (last (__ * 2 [3 4 5])) (reduce * 2 [3 4 5]) 120))))

;;; Problem 59 - Juxtaposition
(deftest test-problem-59
  (let [v1 (fn [& fns]
             (fn [& xs]
               (map #(apply % xs) fns)))
        __ v1]
    (is (= [21 6 1] ((__ + max min) 2 3 5 1 6 4)))
    (is (= ["HELLO" 5] ((__ #(.toUpperCase %) count) "hello")))
    (is (= [2 6 4] ((__ :a :c :b) {:a 2, :b 4, :c 6, :d 8 :e 10})))))

;;; Problem 58 - Function composition
(deftest test-problem-58
  (let [v1 (fn [& fns]
             (fn [& xs]
               (let [[f & rfns] (reverse fns)]
                 (reduce #(%2 %)
                         (apply f xs)
                         rfns))))
        v2 (fn [& fns]
             (reduce (fn [f g]
                       (fn [& xs]
                         (f (apply g xs))))
                     fns))
        __ v2]
    (is (= [3 2 1] ((__ rest reverse) [1 2 3 4])))
    (is (= 5 ((__ (partial + 3) second) [1 2 3 4])))
    (is (= true ((__ zero? #(mod % 8) +) 3 5 7 9)))
    (is (= "HELLO" ((__ #(.toUpperCase %) #(apply str %) take) 5 "hello world")))))

;;; Problem 57 - Simple Recursion
(deftest test-problem-57
  (let [v1 [5 4 3 2 1] 
        __ v1]
    (is (= __ ((fn foo [x] (when (> x 0) (conj (foo (dec x)) x))) 5)))))

;;; Problem 56 - Find Distinct Items
(deftest test-problem-56
  (let [v1 (fn [xs]
             (loop [[e & c] xs a [] d #{}]
               (if e
                 (recur c
                        (if (d e) a (conj a e))
                        (conj d e))
                 a)))
        __ v1]
    (is (= (__ [1 2 1 3 1 2 4]) [1 2 3 4]))
    (is (= (__ [:a :a :b :b :c :c]) [:a :b :c]))
    (is (= (__ '([2 4] [1 2] [1 3] [1 3])) '([2 4] [1 2] [1 3])))
    (is (= (__ (range 50)) (range 50)))))

(run-tests)