Posts A Random Job Interview Challenge In Clojure become a patron
Post
Cancel

A Random Job Interview Challenge In Clojure

It’s evening and I’m listening to some music while I’m casually browsing the web. After a couple of minutes This tweet came about:

Since I recently started learning Clojure, and I regularly do 4clojure exercises, this problem seemed intriguing, so I decided to try to solve it immediately. I fired up my REPL, and within several minutes i came up with:

1
2
3
4
(interleave
 (map str (map first (partition-by identity "aaaabbbcca")))
 (map count (partition-by identity "aaaabbbcca")))
=> ("a" 4 "b" 3 "c" 2 "a" 1)

Yaay! It works! But it is not exactly what was asked for. Nor is it very ‘clean’, so to say. What bothers me the most in this solution is that i have repetitive code, so I decided to solve that with let:

1
2
3
4
(let [x (partition-by identity "aaaabbbcca")]
  (interleave (map str (map first x))
              (map count x)))
=> ("a" 4 "b" 3 "c" 2 "a" 1)

Now it’s a little bit better, code-wise, but result is still not exactly right. So I decided to replace interleave with map list, since it gets us to where we need to be:

1
2
3
4
(let [x (partition-by identity "aaaabbbcca")]
  (map list (map str (map first x))
            (map count x)))
=> (("a" 4) ("b" 3) ("c" 2) ("a" 1))

Then I immediately realised, that it can be even better. Instead of repeating map twice in (map str (map first x)), I replaced it with (map (comp str first) x) and it’s little bit cleaner:

1
2
3
4
(let [x (partition-by identity "aaaabbbcca")]
    (map list (map (comp str first) x)
              (map count x)))
=> (("a" 4) ("b" 3) ("c" 2) ("a" 1))

And then i just put everything into a function, since the task was to make a function that can be reused. I was only left with a burden to name this function, which was conveniently named chop-chop :)

1
2
3
4
5
6
(defn chop-chop [coll]
  (let [x (partition-by identity coll)]
    (map list (map (comp str first) x)
                (map count x))))
=> (chop-chop "aaaabbbcca")
=> (("a" 4) ("b" 3) ("c" 2) ("a" 1))

I must say that it felt great to solve a problem within several minutes (albeit it was not that hard), since I’m only at the beginning of my journey with Clojure.

BTW, I’m sure this function can be improved, so feel free to suggest changes.

This post is licensed under CC BY 4.0 by the author.