Space Age Problem – Haskell [Problem Solved]

Background

This problem comes courtesy of the great folks over at Exercism. I highly recommend jumping on their Haskell track to apply your knowledge of Haskell.


The Problem

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

  • Mercury: orbital period 0.2408467 Earth years
  • Venus: orbital period 0.61519726 Earth years
  • Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds
  • 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.


Knowledge You Need to Solve This Problem

The Solution

To solve this problem, we’ll complete the ageOn function, which will calculate the age on a given planet based on the age in seconds. We’ll use the starting Planet data type and calculate the age using each planet’s orbital period relative to Earth years.

Steps to Solution

  1. Define Earth’s Orbital Period in Seconds:
    • Use 31557600 seconds for one Earth year, as specified in the instructions.
  2. Define Each Planet’s Orbital Period Relative to Earth:
    • Each planet has a different orbital period in Earth years, which we’ll use to scale the age.
  3. Implement ageOn Function:
    • ageOn takes a planet and an age in seconds.
    • Convert the age in seconds to Earth years.
    • Adjust for each planet by dividing by the planet’s orbital period.

Haskell Code

Here’s the completed Haskell code:

-- Define the Planet data type
data Planet = Mercury
            | Venus
            | Earth
            | Mars
            | Jupiter
            | Saturn
            | Uranus
            | Neptune

-- Earth's orbital period in seconds
earthYearInSeconds :: Float
earthYearInSeconds = 31557600

-- Function to get the orbital period of each planet in Earth years
orbitalPeriod :: Planet -> Float
orbitalPeriod Mercury = 0.2408467
orbitalPeriod Venus   = 0.61519726
orbitalPeriod Earth   = 1.0
orbitalPeriod Mars    = 1.8808158
orbitalPeriod Jupiter = 11.862615
orbitalPeriod Saturn  = 29.447498
orbitalPeriod Uranus  = 84.016846
orbitalPeriod Neptune = 164.79132

-- Calculate the age on a given planet based on the age in seconds
ageOn :: Planet -> Float -> Float
ageOn planet seconds = seconds / (earthYearInSeconds * orbitalPeriod planet)

-- Usage example: Calculate age on Earth for someone who is 1,000,000,000 seconds old
main :: IO ()
main = do
    let ageInSeconds = 1000000000
    print $ ageOn Earth ageInSeconds    
-- Should output approximately 31.69
    print $ ageOn Mercury ageInSeconds  
-- Calculate age on other planets if needed
    print $ ageOn Venus ageInSeconds
    print $ ageOn Mars ageInSeconds
    print $ ageOn Jupiter ageInSeconds
    print $ ageOn Saturn ageInSeconds
    print $ ageOn Uranus ageInSeconds
    print $ ageOn Neptune ageInSeconds

Explanation

  1. earthYearInSeconds:
    • Defines the number of seconds in one Earth year.
  2. orbitalPeriod:
    • Matches each Planet value to its orbital period in Earth years. This function is key to adjusting for the different year lengths on each planet.
  3. ageOn:
    • Converts seconds to Earth years by dividing by earthYearInSeconds.
    • Then it divides by the orbital period of the given planet (using orbitalPeriod planet) to get the age on that planet.

Example Usage

When running the main function, you should see output like this:

31.69         -- Earth
131.57        -- Mercury
51.51         -- Venus
16.85         -- Mars
2.67          -- Jupiter
1.08          -- Saturn
0.38          -- Uranus
0.19          -- Neptune

Each number represents the age in years for someone who is 1,000,000,000 seconds old on each planet.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *