Exercism v3 launches on Sept 1st 2021. Learn more! 🚀🚀🚀
Avatar of vaeng

vaeng's solution

to Space Age in the Clojure Track

Published at Jan 25 2021 · 0 comments
Test suite

Given an age in seconds, calculate how old someone would be on:

  • Earth: orbital period 365.25 Earth days, or 31557600 seconds
  • Mercury: orbital period 0.2408467 Earth years
  • Venus: orbital period 0.61519726 Earth years
  • Mars: orbital period 1.8808158 Earth years
  • Jupiter: orbital period 11.862615 Earth years
  • Saturn: orbital period 29.447498 Earth years
  • Uranus: orbital period 84.016846 Earth years
  • Neptune: orbital period 164.79132 Earth years

So if you were told someone were 1,000,000,000 seconds old, you should be able to say that they're 31.69 Earth-years old.

If you're wondering why Pluto didn't make the cut, go watch this youtube video.


Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial. http://pine.fm/LearnToProgram/?Chapter=01

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.


(ns space-age-test
  (:require [clojure.test :refer [deftest is]]

(defn- rounds-to
  [expected actual]
  (is (= (Math/round (* 100.0 expected))
         (Math/round (* 100.0 actual)))))

(deftest age-in-earth-years
  (rounds-to 31.69 (space-age/on-earth 1000000000)))

(deftest age-in-mercury-years
  (let [seconds 2134835688]
    (rounds-to 67.65 (space-age/on-earth seconds))
    (rounds-to 280.88 (space-age/on-mercury seconds))))

(deftest age-in-venus-years
  (let [seconds 189839836]
    (rounds-to 6.02 (space-age/on-earth seconds))
    (rounds-to 9.78 (space-age/on-venus seconds))))

(deftest age-on-mars
  (let [seconds 2329871239]
    (rounds-to 73.83 (space-age/on-earth seconds))
    (rounds-to 39.25 (space-age/on-mars seconds))))

(deftest age-on-jupiter
  (let [seconds 901876382]
    (rounds-to 28.58 (space-age/on-earth seconds))
    (rounds-to 2.41 (space-age/on-jupiter seconds))))

(deftest age-on-saturn
  (let [seconds 3000000000]
    (rounds-to 95.06 (space-age/on-earth seconds))
    (rounds-to 3.23 (space-age/on-saturn seconds))))

(deftest age-on-uranus
  (let [seconds 3210123456]
    (rounds-to 101.72 (space-age/on-earth seconds))
    (rounds-to 1.21 (space-age/on-uranus seconds))))

(deftest age-on-neptune
  (let [seconds 8210123456]
    (rounds-to 260.16 (space-age/on-earth seconds))
    (rounds-to 1.58 (space-age/on-neptune seconds))))
(ns space-age)

(def seconds-per-earth-year 31557600.)

(def periods
  {"earth"     1.
   "mercury"   0.2408467
   "venus"     0.61519726
   "mars"      1.8808158
   "jupiter"  11.862615
   "saturn"   29.447498
   "uranus"   84.016846
   "neptune" 164.79132})

(defn- convert [planet seconds]
  (-> seconds
      (/ seconds-per-earth-year)
      (/ (periods planet))))

(defn- add-planet-function-to-ns [planet]
  (intern *ns* (symbol (str "on-" planet))
          (partial convert planet)))

(doseq [planet (keys periods)]
  (add-planet-function-to-ns planet))

Community comments

Find this solution interesting? Ask the author a question to learn more.

vaeng's Reflection

I think I could change the strings in the period map to keys to make the lookup faster, right?