I found this very nice website called Exercism where you can solve little puzzles and wait for mentoring to comment your answer. The mentor helps you to discuss any doubts about your solution and also to help you look at the exercise from a different perspective.

The platform was created by Katrina Owen which is a well-known developer from the Ruby community. The main idea of the platform is to help beginners to explore advanced features of a particular programming language while solving simple problems.

Take a look at this example of how you should act while solving a specific problem at the platform: Bob's problem.

I will post solutions using Clojure, but I'll probably post solutions in Lisp too.

Let's begin:

Bob's problem

You can read the problem's statement by subscribing in the platform. Take a look!!

The following code is my solution to the same puzzle you watched at the video above.

(ns bob)

(defn uppercase? [s]
  (every? #(Character/isUpperCase %)
          (clojure.string/replace s #"\?|\!" "")))

(def lowercase? (complement uppercase?))

(defn regular-question? [s]
  (and (lowercase? s) (re-find #"\?$" s)))

(defn yell-question? [s]
  (and (uppercase? s) (re-find #"\?$" s)))

(defn said-something? [s]
  (empty? (clojure.string/replace s #"\s" "")))

(def yell? uppercase?)

(defn response-for [s]
    (regular-question? s)
    (yell-question? s)
    "Calm down, I know what I'm doing!"
    (yell? s)
    "Whoa, chill out!"
    (said-something? s)
    "Fine. Be that way!"

All of the tests passed, however there is certainly space for improvements there.

RNA transcription

Problem statement:

Given a DNA sequence, return it's complement RNA

The four nucleotides found in the DNA are adenine (A), cytosine (C), guanine (G) and thiamine (T).

And the four nicleotides found in the RNA are adenine (A), cytosine (C), guanine (G) and uracile (U).

Therefore, the transcription table is:

G -> C
C -> G
T -> A
A -> U


The first solution to the problem was using recursion. Date: 2018-09-17

(ns rna-transcription)

(defn to-rna [dna]
  (let [tradutor {\G \C, \C \G, \T \A, \A \U}]
    (if (empty? dna)
      (str (get tradutor (first dna)) (to-rna (rest dna))))))

But, we can already think in a better alternative solution:

(def tradutor {\G \C, \C \G, \T \A, \A \U})

(defn to-rna2 [dna]
  (loop [dna dna
         res ""]
    (if (empty? dna)
      (recur (rest dna)
             (str res (get tradutor (first dna)))))))

Now, at least the recursion is in tail position and Clojure can procede with Tail Call Optimization (TCO) through the JVM.

However, during the readings of Programming Clojure book, we have a basic guide of how to write good Clojure code and one of the items is:

Know the sequence library. You usually can write code without using recursion or implementing lazy API – Programming Clojure

So, let's try to produce a solution without the usage of recursion:

(defn to-rna3 [dna]
  (->> dna
       (partition 1)
       (map #(get tradutor (first %)))
       (apply str)))

The main functionalities used are: a macro thread-last and the functions partition, map and apply.