exercism/elixir/space-age/lib/space_age.ex

39 lines
947 B
Elixir

defmodule SpaceAge do
@type planet ::
:mercury
| :venus
| :earth
| :mars
| :jupiter
| :saturn
| :uranus
| :neptune
@type factors :: %{planet => float}
@factors %{
mercury: 0.2408467,
venus: 0.61519726,
earth: 1.0,
mars: 1.8808158,
jupiter: 11.862615,
saturn: 29.447498,
uranus: 84.016846,
neptune: 164.79132
}
@seconds_in_year 31_557_600
defguardp is_planet(planet) when is_map_key(@factors, planet)
@doc """
Return the number of years a person that has lived for 'seconds' seconds is
aged on 'planet', or an error if 'planet' is not a planet.
"""
@spec age_on(planet, pos_integer) :: {:ok, float} | {:error, String.t()}
def age_on(planet, seconds) when is_planet(planet),
do: {:ok, seconds / (@factors[planet] * @seconds_in_year)}
def age_on(_planet, _seconds),
do: {:error, "not a planet"}
end