For someone without previous Lisp experience, the hardest part of learning Clojure programming seems to be the functional way of doing things. It is like math, one really needs to do some exercises in order to master it. At this point, 4clojure.com seems to be the best place for getting such exercises. It has a lot of problems for new clojurians to solve. These problems ask one to fill in the blank __ so the given expressions are true. To give a little challenge, some clojure built-in functions are forbidden to use for some problems. New problems are added from time to time on the site, so it surely can keep me entertained for a while.

I just finished the first 50 problems and think it might be helpful to post the solutions here. I tried to be functional and avoided using loops in the code. Some solutions are skipped as they seem trivial even for a functional newbie like myself. My solutions are probably just awful, but it is a fun experience nevertheless. I will post more solutions when I am done with them (Solutions No.50-75 and 76-100) Update: please find better solutions for problem 21, 27 and 44, contributed by visitors in the comments section below. Thank you guys for the nice solutions. I appreciate it.

; (= (__ '(4 5 6 7) 2) 6)

; forbidden: nth

(fn [coll n]

((apply comp (cons first (repeat n rest))) coll))

; We first compose n rest functions to get progressively shorter lists

(fn [coll n]

(first (nthnext coll n)))

; (= (__ '(1 2 3 3 1)) 5)

; forbidden: count

#(

**reduce**+ (

**map**(fn [x] 1) %))

; We just turn each element into 1 and then add them up

; Note that (fn [x] 1) can be replaced by (constantly 1)

; (= (__ [1 2 3 4 5]) [5 4 3 2 1])

; forbidden: reverse

#(into () %)

; We exploit the property of the list, which alway add new element

; in front of the head. Also that the clojure sequences' equality

; evaluation is element based, so [1 2 3] equals to '(1 2 3)

; (= (__ 6) '(1 1 2 3 5 8))

(fn [x]

(take x

((fn fib [a b]

(cons a (lazy-seq (fib b (+ a b)))))

1 1)))

; we first recursively construct a lazy sequence of infinite number of

; fibonacci numbers

; (true? (__ '(1 1 3 3 1 1)))

(fn [coll]

(let [rc (reverse coll) n (count coll)]

(every? identity

(

**map**#(= (nth coll %) (nth rc %)) (range (/ (dec n) 2))))))

; we naively compare half of the pairs of elment e(i) and e(n-i-1)

; (= (__ '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6))

; forbidden: flatten

(fn flt [coll]

(let [l (first coll) r (next coll)]

(concat

(if (sequential? l)

(flt l)

[l])

(

**when**(sequential? r)

(flt r)))))

; we basically treat the nested collection as a tree and recursively

; (= (__ "HeLlO, WoRlD!") "HLOWRD")

(fn [coll]

(apply str (

**filter**#(Character/isUpperCase %) coll)))

; note the use of apply here, as str takes a number of args instead

; of a character collection

; (= (apply str (__ "Leeeeeerrroyyy")) "Leroy")

(fn cmprs [coll]

(

**when-let**[[f & r] (seq coll)]

(if (= f (first r))

(cmprs r)

(cons f (cmprs r)))))

; Basically a variant of the filter function. Note the sequence

; 31: Write a function which packs consecutive duplicates into sub-lists.

; (= (__ [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3)))

(fn [coll]

((fn pack [res prev coll]

(**if-let** [[f & r] (seq coll)]

(if (= f (first prev))

(pack res (conj prev f) r)

(pack (conj res prev) [f] r)))

(conj res prev))

[] [(first coll)] (rest coll)))

; res is the final list, prev keeps the immediate previous sub-list.

; A much simpler version use partition-by:

#(partition-by identity %)

; 33: Write a function which replicates each element of a sequence

; (= (__ [1 2 3] 2) '(1 1 2 2 3 3))

(fn [coll n]

(apply concat (

**map**#(repeat n %) coll)))

; or more succintly:

(fn [coll n]

(

**mapcat**#(repeat n %) coll))

; 34: Write a function which creates a list of all integers in a

; (= (__ 1 4) '(1 2 3))

; forbidden: range

(fn [s e]

(take (- e s) (iterate inc s)))

; 38: Write a function which takes a variable number of parameters

; forbidden: max, max-key

; (= (__ 1 8 3 4) 8)

(fn [x & xs]

(

**reduce**#(if (< %1 %2) %2 %1) x xs))

; 39: Write a function which takes two sequences and returns the first

; (= (__ [1 2] [3 4 5 6]) '(1 3 2 4))

; forbidden: interleave

#(

**mapcat**vector %1 %2)

; 40: Write a function which separates the items of a sequence by

; (= (__ 0 [1 2 3]) [1 0 2 0 3])

; forbidden: interpose

(fn [sep coll]

(drop-last (

**mapcat**vector coll (repeat sep))))

; 41: Write a function which drops every Nth item from a sequence.

; (= (__ [1 2 3 4 5 6 7 8] 3) [1 2 4 5 7 8])

(fn [coll n]

(flatten

(concat

(**map** #(drop-last %) (partition n coll))

(take-last (rem (count coll) n) coll))))

; We partition the sequence, drop last one from each, then stitch them

; 42: Write a function which calculates factorials.

; (= (__ 5) 120)

(fn [n]

(apply * (range 1 (inc n))))

; clojure arithmetic functions can take a variable number of arguments

; 43: Write a function which reverses the interleave process into n

; (= (__ [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6)))

(fn [coll n]

(apply

**map**list (partition n coll)))

; exploit map function's ability to take a variable number of

; 44: Write a function which can rotate a sequence in either direction.

; (= (__ 2 [1 2 3 4 5]) '(3 4 5 1 2))

; (= (__ -2 [1 2 3 4 5]) '(4 5 1 2 3))

(fn [n coll]

(let [ntime (if (neg? n) (- n) n)

lshift #(concat (rest %) [(first %)])

rshift #(cons (last %) (drop-last %))]

((apply comp (repeat ntime (if (neg? n) rshift lshift))) coll)))

; 50: Write a function which takes a sequence consisting of items

; (= (set (__ [1 :a 2 :b 3 :c])) #{[1 2 3] [:a :b :c]})

#(vals (group-by type %))

### The solution to problem 21

The solution to problem 21 seems a bit too complicated:

`(fn [coll n] (first (drop n coll)))`

### agreed

You are right, that solution is too complicated. When I wrote that, I had not been used to the functional way of thinking, which is more high level and declarative. As you can see, that solution was still trying to do things sequentially, basically trying to do a loop by function composition. Your solution is more declarative: just drops the last n elements and does not care about how they are dropped.

Another lesson is that one really needs to get acquainted with seq library of Clojure. I did not know about the drop function when I wrote my solution.

Thanks for sharing your solution. I appreciate it.

### Problem 27

Solution to the problem 27 is as simple as:

#(= (seq %) (reverse %))

### I wish they would put some of these up alongside the problems

I really love how elegantly you have solved these solutions, far better than my attempts (the functional way of thinking still makes my brain hurt) Thanks for taking the time to document your thought processes along with the problems. I've found it more useful than reading documentation as the problem domain is more succinct.

Thanks!

### Thank you for your nice words

I am glad that this is helpful. Happy Clojuring

### problem #21 - your solution

problem #21 - your solution is confusing..simple one below

(fn[col x ]

(first (drop x col)))

### duplicate

citizen428 has already posted the same solution. Thank you for stopping by.

### For exercise number 21... could be done shorter

`#(.get %1 %2)`

### Problem 26 - fibonacci

Mine is a bit more verbose...`(fn [ind] (map (fn fib [x] (if (<= x 2) 1 (+ (fib (- x 1)) (fib (- x 2))))) (map #(+ 1 %) (range ind))))`

Basically, make a fibonacci function, map it to a range offset by 1.

### Problem 27 - palindrome?

`(fn [x] (= (reverse x) (seq s)))`

### Problem 30 - compression

`#(map first (partition-by identity %))`

`partition-by identity` separates into a seq separated by sections of elements. then you get the first of each section and return the seq.

### For program 40

`#(mapcat vector (repeat (count %2) %1) %2)`

You can use your previous solution, and mapcat (or interleave) 2 seqs.

### Sorry, the correct and better way:

`#(drop-last (interleave %2 (repeat (count %2) %1)))`

### Problem 27

27. (fn [what] (= (reverse what) ((comp reverse reverse) what)))

### Problem 44

I have a solution that I believe to be just a bit more concise than the previous comment.

(fn rotate[n seq]

(let [n (mod n (count seq))]

(concat (drop n seq) (take n seq))))

### a simpler solution for

a simpler solution for #28:

(fn flat [x] (apply concat (map #(if (sequential? %) (flat %) [%]) x)))

### (slightly pedantic) bug in solution #30

Here's the bug:

user=> (cmprs [1 1 2 2 nil nil])

(1 2)

Because (first r) returns nil if r is emtpy, any trailing nils in the input collection will be lost. This fixes it:

(defn cmprs2 [coll]

(when-let [[f & r] (seq coll)]

(if (and (nil? f) (empty? r))

(list f)

(if (= f (first r))

(cmprs2 r)

(cons f (cmprs2 r))))))

user=> (cmprs2 [1 1 2 2 nil nil])

(1 2 nil)

### Problem 21

I checked the code of drop and this is the solution I used.

(fn element-at [list n]

(let [go (fn [list n] (if (and (pos? n) list) (recur (rest list) (dec n)) list))]

(first(go list n))))

### Problem 41

Solution for Problem #41 can be slightly altered to handle the partitioned items in one go, by checking the size of item:

(fn [col n] (flatten (concat (map #(if (= n (count %)) (drop-last %) %) (partition-all n col)))))

BTW, great site, very helpful to see discussions.

## Problem 44

I struggled with that one a lot. My first solution was about twice as long as yours. Then I figured out it was simply a matter of splitting the collection in half at the right place, then joining the two pieces back together in the opposite order.

#(let [

[l r] (split-at (mod % (count %2)) %2)]

(concat r l))