diff --git a/haskell/space-age/.exercism/config.json b/haskell/space-age/.exercism/config.json new file mode 100644 index 0000000..acced26 --- /dev/null +++ b/haskell/space-age/.exercism/config.json @@ -0,0 +1,31 @@ +{ + "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", + "authors": [ + "etrepum" + ], + "contributors": [ + "iHiD", + "joshgoebel", + "kytrinyx", + "mttakai", + "petertseng", + "ppartarr", + "rbasso", + "sharno", + "sshine", + "tejasbubane" + ], + "files": { + "solution": [ + "src/SpaceAge.hs" + ], + "test": [ + "test/Tests.hs" + ], + "example": [ + "examples/success-double/src/SpaceAge.hs" + ] + }, + "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", + "source_url": "http://pine.fm/LearnToProgram/?Chapter=01" +} diff --git a/haskell/space-age/.exercism/metadata.json b/haskell/space-age/.exercism/metadata.json new file mode 100644 index 0000000..1d9de95 --- /dev/null +++ b/haskell/space-age/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"haskell","exercise":"space-age","id":"f8e96bcda9cb4bf9af558268e7d8199e","url":"https://exercism.org/tracks/haskell/exercises/space-age","handle":"JBiason","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/haskell/space-age/HELP.md b/haskell/space-age/HELP.md new file mode 100644 index 0000000..accd99e --- /dev/null +++ b/haskell/space-age/HELP.md @@ -0,0 +1,88 @@ +# Help + +## Running the tests + +To run the test suite, execute the following command: + +```bash +stack test +``` + +#### If you get an error message like this... + +``` +No .cabal file found in directory +``` + +or + +``` +RedownloadInvalidResponse Request { +... +} + "/home/username/.stack/build-plan/lts-xx.yy.yaml" (Response {responseStatus = Status {statusCode = 404, statusMessage = "Not Found"}, +``` + +You are probably running an old stack version and need +to upgrade it. Try running: + +```bash +stack upgrade +``` + +Or see other options for upgrading at [Stack documentation](https://docs.haskellstack.org/en/stable/install_and_upgrade/#upgrade). + +#### Otherwise, if you get an error message like this... + +``` +No compiler found, expected minor version match with... +Try running "stack setup" to install the correct GHC... +``` + +Just do as it says and it will download and install +the correct compiler version: + +```bash +stack setup +``` + + +If you want to play with your solution in GHCi, just run the command: + +```bash +stack ghci +``` + +## Submitting your solution + +You can submit your solution using the `exercism submit src/SpaceAge.hs` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [Haskell track's documentation](https://exercism.org/docs/tracks/haskell) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +## Getting Started + +Please refer to the [installation](https://exercism.io/tracks/haskell/installation) +and [learning](https://exercism.io/tracks/haskell/learning) help pages. + +## Feedback, Issues, Pull Requests + +The [exercism/haskell](https://github.com/exercism/haskell) repository on +GitHub is the home for all of the Haskell exercises. + +If you have feedback about an exercise, or want to help implementing a new +one, head over there and create an issue. We'll do our best to help you! +{{ with .Spec.Credits }} \ No newline at end of file diff --git a/haskell/space-age/README.md b/haskell/space-age/README.md new file mode 100644 index 0000000..6cb793a --- /dev/null +++ b/haskell/space-age/README.md @@ -0,0 +1,59 @@ +# Space Age + +Welcome to Space Age on Exercism's Haskell Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +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. + +If you're wondering why Pluto didn't make the cut, go watch [this +youtube video](http://www.youtube.com/watch?v=Z_2gbGXzFbs). + +In this exercise, we provided the definition of the +[algebric data type](http://learnyouahaskell.com/making-our-own-types-and-typeclasses) +named `Planet`. +You need to implement the `ageOn` function, that calculates how many +years old someone would be on a `Planet`, given an age in seconds. + +Your can use the provided signature if you are unsure about the types, but +don't let it restrict your creativity: + +```haskell +ageOn :: Planet -> Float -> Float +``` + +## Source + +### Created by + +- @etrepum + +### Contributed to by + +- @iHiD +- @joshgoebel +- @kytrinyx +- @mttakai +- @petertseng +- @ppartarr +- @rbasso +- @sharno +- @sshine +- @tejasbubane + +### Based on + +Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial. - http://pine.fm/LearnToProgram/?Chapter=01 \ No newline at end of file diff --git a/haskell/space-age/examples/success-double/package.yaml b/haskell/space-age/examples/success-double/package.yaml new file mode 100644 index 0000000..b352276 --- /dev/null +++ b/haskell/space-age/examples/success-double/package.yaml @@ -0,0 +1,16 @@ +name: space-age + +dependencies: + - base + +library: + exposed-modules: SpaceAge + source-dirs: src + +tests: + test: + main: Tests.hs + source-dirs: test + dependencies: + - space-age + - hspec diff --git a/haskell/space-age/examples/success-rational/package.yaml b/haskell/space-age/examples/success-rational/package.yaml new file mode 100644 index 0000000..b352276 --- /dev/null +++ b/haskell/space-age/examples/success-rational/package.yaml @@ -0,0 +1,16 @@ +name: space-age + +dependencies: + - base + +library: + exposed-modules: SpaceAge + source-dirs: src + +tests: + test: + main: Tests.hs + source-dirs: test + dependencies: + - space-age + - hspec diff --git a/haskell/space-age/examples/success-rational/src/SpaceAge.hs b/haskell/space-age/examples/success-rational/src/SpaceAge.hs new file mode 100644 index 0000000..3491bf9 --- /dev/null +++ b/haskell/space-age/examples/success-rational/src/SpaceAge.hs @@ -0,0 +1,24 @@ +module SpaceAge (Planet(..), ageOn) where + +data Planet = Mercury + | Venus + | Earth + | Mars + | Jupiter + | Saturn + | Uranus + | Neptune + +ageOn :: Real a => Planet -> a -> Rational +ageOn planet seconds = toRational seconds / (earthPeriod * planetMultiplier) + where + planetMultiplier = case planet of + Mercury -> 0.2408467 + Venus -> 0.61519726 + Earth -> 1 + Mars -> 1.8808158 + Jupiter -> 11.862615 + Saturn -> 29.447498 + Uranus -> 84.016846 + Neptune -> 164.79132 + earthPeriod = 31557600 diff --git a/haskell/space-age/package.yaml b/haskell/space-age/package.yaml new file mode 100644 index 0000000..9c7afd2 --- /dev/null +++ b/haskell/space-age/package.yaml @@ -0,0 +1,21 @@ +name: space-age +version: 1.2.0.6 + +dependencies: + - base + +library: + exposed-modules: SpaceAge + source-dirs: src + ghc-options: -Wall + # dependencies: + # - foo # List here the packages you + # - bar # want to use in your solution. + +tests: + test: + main: Tests.hs + source-dirs: test + dependencies: + - space-age + - hspec diff --git a/haskell/space-age/space-age.cabal b/haskell/space-age/space-age.cabal new file mode 100644 index 0000000..7c4f6e1 --- /dev/null +++ b/haskell/space-age/space-age.cabal @@ -0,0 +1,34 @@ +cabal-version: 1.12 + +-- This file has been generated from package.yaml by hpack version 0.34.2. +-- +-- see: https://github.com/sol/hpack + +name: space-age +version: 1.2.0.6 +build-type: Simple + +library + exposed-modules: + SpaceAge + other-modules: + Paths_space_age + hs-source-dirs: + src + ghc-options: -Wall + build-depends: + base + default-language: Haskell2010 + +test-suite test + type: exitcode-stdio-1.0 + main-is: Tests.hs + other-modules: + Paths_space_age + hs-source-dirs: + test + build-depends: + base + , hspec + , space-age + default-language: Haskell2010 diff --git a/haskell/space-age/src/SpaceAge.hs b/haskell/space-age/src/SpaceAge.hs new file mode 100644 index 0000000..93d5dbb --- /dev/null +++ b/haskell/space-age/src/SpaceAge.hs @@ -0,0 +1,20 @@ +module SpaceAge (Planet(..), ageOn) where + +data Planet = Mercury + | Venus + | Earth + | Mars + | Jupiter + | Saturn + | Uranus + | Neptune + +ageOn :: Planet -> Float -> Float +ageOn Earth seconds = seconds / 60 / 60 / 24 / 365.25 +ageOn Mercury seconds = ageOn Earth seconds / 0.2408467 +ageOn Venus seconds = ageOn Earth seconds / 0.61519726 +ageOn Mars seconds = ageOn Earth seconds / 1.8808158 +ageOn Jupiter seconds = ageOn Earth seconds / 11.862615 +ageOn Saturn seconds = ageOn Earth seconds / 29.447498 +ageOn Uranus seconds = ageOn Earth seconds / 84.016846 +ageOn Neptune seconds = ageOn Earth seconds / 164.79132 diff --git a/haskell/space-age/stack.yaml b/haskell/space-age/stack.yaml new file mode 100644 index 0000000..35c2e5b --- /dev/null +++ b/haskell/space-age/stack.yaml @@ -0,0 +1 @@ +resolver: lts-16.21 diff --git a/haskell/space-age/stack.yaml.lock b/haskell/space-age/stack.yaml.lock new file mode 100644 index 0000000..c646f0b --- /dev/null +++ b/haskell/space-age/stack.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + size: 532413 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/21.yaml + sha256: 7b5cac89352fa4a88606dc6cb250aee9291f21e2e988d464065f5aa51f5de33d + original: lts-16.21 diff --git a/haskell/space-age/test/Tests.hs b/haskell/space-age/test/Tests.hs new file mode 100644 index 0000000..7561f9e --- /dev/null +++ b/haskell/space-age/test/Tests.hs @@ -0,0 +1,79 @@ +{-# OPTIONS_GHC -fno-warn-type-defaults #-} +{-# LANGUAGE RecordWildCards #-} + +import Data.Foldable (for_) +import Data.Function (on) +import Test.Hspec (Spec, describe, it, shouldBe) +import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) + +import SpaceAge (Planet(..), ageOn) + +main :: IO () +main = hspecWith defaultConfig {configFastFail = True} specs + +specs :: Spec +specs = describe "ageOn" $ for_ cases test + where + -- Here we used `fromIntegral`, `fromRational` and `toRational` to + -- generalize the test suite, allowing any function that takes a + -- `Planet` and a number, returning an instance of `Real`. + test Case{..} = it description $ expression `shouldBeAround` expected + where + expression = fromRational + . toRational + . ageOn planet + . fromIntegral + $ seconds + shouldBeAround = shouldBe `on` roundTo 2 + roundTo n = (/ 10 ^ n) . fromIntegral . round . (* 10 ^ n) + +data Case = Case { description :: String + , planet :: Planet + , seconds :: Integer + , expected :: Double + } + +cases :: [Case] +cases = [ Case { description = "Earth" + , planet = Earth + , seconds = 1000000000 + , expected = 31.69 + } + , Case { description = "Mercury" + , planet = Mercury + , seconds = 2134835688 + , expected = 280.88 + } + , Case { description = "Venus" + , planet = Venus + , seconds = 189839836 + , expected = 9.78 + } + , Case { description = "Mars" + , planet = Mars + , seconds = 2129871239 + , expected = 35.88 + } + , Case { description = "Jupiter" + , planet = Jupiter + , seconds = 901876382 + , expected = 2.41 + } + , Case { description = "Saturn" + , planet = Saturn + , seconds = 2000000000 + , expected = 2.15 + } + , Case { description = "Uranus" + , planet = Uranus + , seconds = 1210123456 + , expected = 0.46 + } + , Case { description = "Neptune" + , planet = Neptune + , seconds = 1821023456 + , expected = 0.35 + } + ] + +-- 33c40fce28c835600282d0bfdc589d7c6d785f6e