Friday, July 4, 2014

Exercism: "Robot name in Clojure"

This is my solution to the Robot name problem in Clojure:

(ns robot)
(defn robot []
(atom {:name ""}))
(defn robot-name [robot]
(let
[current-name (:name @robot)
random-name
(fn []
(let
[capital-letters
(map char (range (int \A) (+ (int \Z) 1)))
num-letters
(count capital-letters)]
(apply
str
(concat
(repeatedly
2
#(nth capital-letters (rand-int num-letters)))
(repeatedly
3
#(rand-int 10))))))]
(if (empty? current-name)
(:name (swap! robot assoc :name (random-name)))
current-name)))
(defn reset-name [robot]
(swap! robot assoc :name ""))
view raw robot-name.clj hosted with ❤ by GitHub

This is the first exercise in which I've used some mutable state features of Clojure, atom in this case.

It also helped me to discover the repeatedly function.

You can nitpick my solution here or see all the exercises I've done so far in this repository.

--------------------------------

Update:

After learning some new stuff, I've been able to simplify the code a bit more:

(ns robot)
(def ^:private capital-letters
(map char (range (int \A) (+ (int \Z) 1))))
(defn- random-name []
(str
(rand-nth capital-letters)
(rand-nth capital-letters)
(rand-int 1000)))
(defn robot []
(atom {:name ""}))
(defn robot-name [robot]
(let
[current-name (:name @robot)]
(if (empty? current-name)
(:name (swap! robot assoc :name (random-name)))
current-name)))
(defn reset-name [robot]
(swap! robot assoc :name ""))
view raw robot1.clj hosted with ❤ by GitHub

I used the :private true metadata key value pair to make capital-letters private, the special defn- macro instead of defn to make random-name private and the random-nth function.

You can nitpick this new version here.

No comments:

Post a Comment