Avatar of shmibs

shmibs's solution

to Space Age in the Elixir Track

Published at Jul 13 2018 · 0 comments
Instructions
Test suite
Solution

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.

Running tests

Execute the tests with:

$ elixir space_age_test.exs

Pending tests

In the test suites, all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by commenting out the relevant @tag :pending with a # symbol.

For example:

# @tag :pending
test "shouting" do
  assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end

Or, you can enable all the tests by commenting out the ExUnit.configure line in the test suite.

# ExUnit.configure exclude: :pending, trace: true

For more detailed information about the Elixir track, please see the help page.

Source

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.

space_age_test.exs

if !System.get_env("EXERCISM_TEST_EXAMPLES") do
  Code.load_file("space_age.exs", __DIR__)
end

ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)

# You need to define a SpaceAge module containing a function age_on that given a
# planet (:earth, :saturn, etc) and a number of seconds returns the age in years
# on that planet as a floating point number.

defmodule SpageAgeTest do
  use ExUnit.Case

  # @tag :pending
  test "age on Earth" do
    input = 1_000_000_000
    assert_in_delta 31.69, SpaceAge.age_on(:earth, input), 0.005
  end

  @tag :pending
  test "age on Mercury" do
    input = 2_134_835_688
    assert_in_delta 67.65, SpaceAge.age_on(:earth, input), 0.005
    assert_in_delta 280.88, SpaceAge.age_on(:mercury, input), 0.005
  end

  @tag :pending
  test "age on Venus" do
    input = 189_839_836
    assert_in_delta 6.02, SpaceAge.age_on(:earth, input), 0.005
    assert_in_delta 9.78, SpaceAge.age_on(:venus, input), 0.005
  end

  @tag :pending
  test "age on Mars" do
    input = 2_329_871_239
    assert_in_delta 73.83, SpaceAge.age_on(:earth, input), 0.005
    assert_in_delta 39.25, SpaceAge.age_on(:mars, input), 0.005
  end

  @tag :pending
  test "age on Jupiter" do
    input = 901_876_382
    assert_in_delta 28.58, SpaceAge.age_on(:earth, input), 0.005
    assert_in_delta 2.41, SpaceAge.age_on(:jupiter, input), 0.005
  end

  @tag :pending
  test "age on Saturn" do
    input = 3_000_000_000
    assert_in_delta 95.06, SpaceAge.age_on(:earth, input), 0.005
    assert_in_delta 3.23, SpaceAge.age_on(:saturn, input), 0.005
  end

  @tag :pending
  test "age on Uranus" do
    input = 3_210_123_456
    assert_in_delta 101.72, SpaceAge.age_on(:earth, input), 0.005
    assert_in_delta 1.21, SpaceAge.age_on(:uranus, input), 0.005
  end

  @tag :pending
  test "age on Neptune" do
    input = 8_210_123_456
    assert_in_delta 260.16, SpaceAge.age_on(:earth, input), 0.005
    assert_in_delta 1.58, SpaceAge.age_on(:neptune, input), 0.005
  end
end
defmodule SpaceAge do
  @type planet :: :mercury | :venus | :earth | :mars | :jupiter
                | :saturn | :neptune | :uranus

  @earth_year_len 31557600
  @year_len_multipliers %{
    mercury: 0.2408467,
    venus: 0.61519726,
    earth: 1,
    mars: 1.8808158,
    jupiter: 11.862615,
    saturn: 29.447498,
    neptune: 164.79132,
    uranus: 84.016846
  }

  @doc """
  Return the number of years a person that has lived for 'seconds' seconds is
  aged on 'planet'.
  """
  @spec age_on(planet, pos_integer) :: float
  def age_on(planet, seconds) do
    seconds / (@year_len_multipliers[planet] * @earth_year_len)
  end
end

Community comments

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

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?