Next round of 4clojure.com solutions

After the first round, ten more 4clojure.com solutions:

(ns com.icyrock.clojure.a4clojure_com.core
  (:use clojure.test))

;;; Problem 30 - Compress a Sequence
(deftest test-problem-30
  (let [pins
        [(fn [xs] (reduce #(if (= (peek %1) %2) %1 (conj %1 %2)) [] xs))
         #(map first (partition-by identity %))]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (apply str (pin "Leeeeeerrroyyy")) "Leroy"))
      (is (= (pin [1 1 2 3 3 2 2 3]) '(1 2 3 2 3)))
      (is (= (pin [[1 2] [1 2] [3 4] [1 2]]) '([1 2] [3 4] [1 2])))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 29 - Get the Caps
(deftest test-problem-29
  (let [pins
        [(fn [s] (apply str (filter #(Character/isUpperCase %) s)))
         #(apply str (re-seq #"[A-Z]" %))
         (fn [s] (-> (re-seq #"[A-Z]" s) (#(apply str %))))]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin "HeLlO, WoRlD!") "HLOWRD"))
      (is (empty? (pin "nothing")))
      (is (= (pin "$#A(*&987Zf") "AZ"))
      (is (= true true))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 28 - Flatten a Sequence
(deftest test-problem-28
  (let [pins
        [(fn ftn [coll]
           (loop [xs coll ys []]
             (if (seq xs)
               (let [x (first xs)
                     nys (if (coll? x) (into ys (ftn x)) (conj ys x))]
                 (recur (rest xs) nys))
               ys)))
         (fn ftn [xs]
           (if (coll? xs)
             (mapcat ftn xs)
             [xs]))]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6)))
      (is (= (pin ["a" ["b"] "c"]) '("a" "b" "c")))
      (is (= (pin '((((:a))))) '(:a)))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 27 - Palindrome Detector
(deftest test-problem-27
  (let [pins
        [#(= (seq %) (reverse %))]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (false? (pin '(1 2 3 4 5))))
      (is (true? (pin "racecar")))
      (is (true? (pin [:foo :bar :foo])))
      (is (true? (pin '(1 1 3 3 1 1))))
      (is (false? (pin '(:a :b :c))))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 26 - Fibonacci Sequence
(deftest test-problem-26
  (let [pins
        [(fn [n]
           (loop [acc [1 1] cnt (count acc)]
             (if (= n cnt)
               (reverse acc)
               (recur (cons (apply + (take 2 acc)) acc) (inc cnt)))))
         (fn [n]
           (take n
                 (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1]))))
         (fn [n]
           (take n
                 ((fn step [a b]
                    (lazy-seq (cons a (step b (+ a b)))))
                  1 1)))]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin 8) '(1 1 2 3 5 8 13 21)))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 25 - Find the odd numbers
(deftest test-problem-25
  (let [pins
        [(partial filter odd?)]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin #{1 2 3 4 5}) '(1 3 5)))
      (is (= (pin [4 2 1 6]) '(1)))
      (is (= (pin [2 2 4 6]) '()))
      (is (= (pin [1 1 1 3]) '(1 1 1 3)))
      (is (= true true))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 24 - Sum It All Up
(deftest test-problem-24
  (let [pins
        [#(reduce + %)]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin '(1 10 3)) 14))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 23 - Reverse a Sequence
(deftest test-problem-23
  (let [pins
        [#(reduce (fn [out in] (cons in out)) [] %)]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin [1 2 3 4 5]) [5 4 3 2 1]))
      (is (= (pin (sorted-set 5 7 2 7)) '(7 5 2)))
      (is (= (pin [[1 2][3 4][5 6]]) [[5 6][3 4][1 2]]))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 22 - Count a Sequence
(deftest test-problem-22
  (let [pins
        [#(loop [cnt 0 acc %]
            (if (empty? acc)
              cnt
              (recur (inc cnt) (rest acc))))
         #(reduce (fn [cnt _] (inc cnt)) 0 %)]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin '(1 2 3 3 1)) 5))
      (is (= (pin "Hello World") 11))
      (is (= (pin [[1 2] [3 4] [5 6]]) 3))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 21 - Nth Element
(deftest test-problem-21
  (let [pins
        [#(first (drop %2 %1))
         #((vec %) %2)]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin '(4 5 6 7) 2) 6))
      (is (= (pin [:a :b :c] 0) :a))
      (is (= (pin [1 2 3 4] 1) 2))
      (is (= (pin '([1 2] [3 4] [5 6]) 2) [5 6]))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

(run-tests)