Tuesday, July 8, 2014

Exercism: "Space Age in Clojure"

This is my solution to the Space Age problem in Clojure.

In the first working iteration I made all "on-planet" functions use the on-earth function.
I also used let forms to avoid magic numbers.
It has a lot of duplication:

(ns space-age)
(defn on-earth [seconds]
(let
[seconds-per-earth-year 31557600.0]
(/ seconds seconds-per-earth-year)))
(defn on-mercury [seconds]
(let
[orbital-period-in-earth-years 0.2408467]
(/ (on-earth seconds) orbital-period-in-earth-years)))
(defn on-venus [seconds]
(let
[orbital-period-in-earth-years 0.61519726]
(/ (on-earth seconds) orbital-period-in-earth-years)))
(defn on-mars [seconds]
(let
[orbital-period-in-earth-years 1.8808158]
(/ (on-earth seconds) orbital-period-in-earth-years)))
(defn on-jupiter [seconds]
(let
[orbital-period-in-earth-years 11.862615]
(/ (on-earth seconds) orbital-period-in-earth-years)))
(defn on-saturn [seconds]
(let
[orbital-period-in-earth-years 29.447498]
(/ (on-earth seconds) orbital-period-in-earth-years)))
(defn on-uranus [seconds]
(let
[orbital-period-in-earth-years 84.016846]
(/ (on-earth seconds) orbital-period-in-earth-years)))
(defn on-neptune [seconds]
(let
[orbital-period-in-earth-years 164.79132]
(/ (on-earth seconds) orbital-period-in-earth-years)))
view raw space-age1.clj hosted with ❤ by GitHub

In the next iteration I played with comp and partial to write the make-on-planet-function factory that can create "on-planet" functions as compositions of the on-earth function:

(ns space-age)
(defn on-earth [seconds]
(let
[seconds-per-earth-year 31557600.0]
(/ seconds seconds-per-earth-year)))
(defn make-on-planet-function [orbital-period-in-earth-years]
(let
[inv-period (/ 1.0 orbital-period-in-earth-years)]
(comp (partial * inv-period) on-earth)))
(def on-mercury (make-on-planet-function 0.2408467))
(def on-venus (make-on-planet-function 0.61519726))
(def on-mars (make-on-planet-function 1.8808158))
(def on-jupiter (make-on-planet-function 11.862615))
(def on-saturn (make-on-planet-function 29.447498))
(def on-uranus (make-on-planet-function 84.016846))
(def on-neptune (make-on-planet-function 164.79132))
view raw space-age2.clj hosted with ❤ by GitHub

Finally for the last version, I wrote a somehow more readable version of make-on-planet-function:

(ns space-age)
(defn on-earth [seconds]
(let
[seconds-per-earth-year 31557600.0]
(/ seconds seconds-per-earth-year)))
(defn make-on-planet-function [orbital-period-in-earth-years]
(fn [seconds]
(/ (on-earth seconds) orbital-period-in-earth-years)))
(def on-mercury (make-on-planet-function 0.2408467))
(def on-venus (make-on-planet-function 0.61519726))
(def on-mars (make-on-planet-function 1.8808158))
(def on-jupiter (make-on-planet-function 11.862615))
(def on-saturn (make-on-planet-function 29.447498))
(def on-uranus (make-on-planet-function 84.016846))
(def on-neptune (make-on-planet-function 164.79132))
view raw space-age3.clj hosted with ❤ by GitHub

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

No comments:

Post a Comment