Working through 4clojure.com problems

4clojure.com is a site that has fill-in type of problems for exercising your Clojure skills. It’s very easy to use and has a built-in unit-test kind of solution checker, including a syntax-highlighting editor. Very simple and neat, like it.

I’ve been working through these, here are solutions to the first 20 basic problems:

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

;;; Problem 20 - Penultimate Element
(deftest test-problem-20
  (let [pins
        [(comp second reverse)]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin (list 1 2 3 4 5)) 4))
      (is (= (pin ["a" "b" "c"]) "b"))
      (is (= (pin [[1 2] [3 4]]) [1 2]))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 19 - Last Element
(deftest test-problem-19
  (let [pins
        [#(nth % (- (count %1) 1))
         (comp first reverse)
         (comp peek vec)
         (fn [x] (reduce #(identity %2) x))]]
    (loop [pin (first pins) rest-pins (rest pins)]
      (is (= (pin [1 2 3 4 5]) 5))
      (is (= (pin ["b" "c" "d"]) "d"))
      (if (not (empty? rest-pins))
        (recur (first rest-pins) (rest rest-pins))))))

;;; Problem 18 - Sequences: filter
(deftest test-problem-18
  (is (= [6 7] (filter #(> % 5) '(3 4 5 6 7)))))

;;; Problem 17 - Sequences: map
(deftest test-problem-17
  (is (= '(6 7 8) (map #(+ % 5) '(1 2 3)))))

;;; Problem 16 - Hello World
(deftest test-problem-16
  (is (= (#(str "Hello, " % "!") "Dave") "Hello, Dave!")))

;;; Problem 15 - Double Down
(deftest test-problem-15
  (is (= (#(* 2 %) 11) 22))
  (is (= ((partial * 2) 11) 22)))

;;; Problem 14 - Intro to Functions
(deftest test-problem-14
  (is (= 8 ((fn add-five [x] (+ x 5)) 3))))

;;; Problem 13 - Sequences: rest
(deftest test-problem-13
  (is (= [20 30 40] (rest [10 20 30 40]))))

;;; Problem 12 - Intro to Sequences
(deftest test-problem-12
  (is (= 3 (first '(3 2 1)))))

;;; Problem 11 - Maps: conj
(deftest test-problem-11
  (is (= {:a 1, :b 2, :c 3} (conj {:a 1} [:b 2] [:c 3]))))

;;; Problem 10 - Intro to Maps
(deftest test-problem-10
  (is (= 20 ((hash-map :a 10, :b 20, :c 30) :b))))

;;; Problem 9 - Sets: conj
(deftest test-problem-9
  (is (= #{1 2 3 4} (conj #{1 4 3} 2))))

;;; Problem 8 - Intro to Sets
(deftest test-problem-8
  (is (= #{:a :b :c :d} (set '(:a :a :b :c :c :c :c :d :d)))))

;;; Problem 7 - Vectors: conj
(deftest test-problem-7
  (is (= [1 2 3 4] (conj [1 2 3] 4))))

;;; Problem 6 - Intro to Vectors
(deftest test-problem-6
  (is (= [:a :b :c] (list :a :b :c) (vec '(:a :b :c)) (vector :a :b :c))))

;;; Problem 5 - Lists: conj
(deftest test-problem-5
  (is (= '(1 2 3 4) (conj '(2 3 4) 1))))

;;; Problem 4 - Intro to Lists
(deftest test-problem-4
  (is (= (list :a :b :c) '(:a :b :c))))

;;; Problem 3 - Intro to Strings
(deftest test-problem-3
  (is (= "HELLO WORLD" (.toUpperCase "hello world"))))

;;; Problem 2 - Simple Math
(deftest test-problem-2
  (is (= (- 10 (* 2 3)) 4)))

;;; Problem 1 - Nothing but the Truth 
(deftest test-problem-1
  (is (= true true)))

(run-tests)

Note that in problems 19 and 20 I added support for multiple solutions. I found out this will be important going forward when problems get harder, so that I can track what I’ve done and save this for later. I think it will be useful for looking at the mistakes I made and make sure I don’t do them again.