From b1ec5d6b1667dcb22c2608c759064c392965d46d Mon Sep 17 00:00:00 2001 From: James Walker Date: Thu, 9 Sep 2021 10:59:03 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20haskell:=20leap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- haskell/leap/HELP.md | 88 +++++++++++++++++++ haskell/leap/README.md | 56 ++++++++++++ .../leap/examples/error-nosig/package.yaml | 16 ++++ .../leap/examples/error-nosig/src/LeapYear.hs | 4 + .../examples/success-standard/package.yaml | 16 ++++ haskell/leap/package.yaml | 21 +++++ haskell/leap/src/LeapYear.hs | 4 + haskell/leap/stack.yaml | 1 + haskell/leap/test/Tests.hs | 66 ++++++++++++++ 9 files changed, 272 insertions(+) create mode 100644 haskell/leap/HELP.md create mode 100644 haskell/leap/README.md create mode 100644 haskell/leap/examples/error-nosig/package.yaml create mode 100644 haskell/leap/examples/error-nosig/src/LeapYear.hs create mode 100644 haskell/leap/examples/success-standard/package.yaml create mode 100644 haskell/leap/package.yaml create mode 100644 haskell/leap/src/LeapYear.hs create mode 100644 haskell/leap/stack.yaml create mode 100644 haskell/leap/test/Tests.hs diff --git a/haskell/leap/HELP.md b/haskell/leap/HELP.md new file mode 100644 index 0000000..25d9769 --- /dev/null +++ b/haskell/leap/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/LeapYear.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/leap/README.md b/haskell/leap/README.md new file mode 100644 index 0000000..65cda6e --- /dev/null +++ b/haskell/leap/README.md @@ -0,0 +1,56 @@ +# Leap + +Welcome to Leap on Exercism's Haskell Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Given a year, report if it is a leap year. + +The tricky thing here is that a leap year in the Gregorian calendar occurs: + +```text +on every year that is evenly divisible by 4 + except every year that is evenly divisible by 100 + unless the year is also evenly divisible by 400 +``` + +For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap +year, but 2000 is. + +## Notes + +Though our exercise adopts some very simple rules, there is more to +learn! + +For a delightful, four minute explanation of the whole leap year +phenomenon, go watch [this youtube video][video]. + +[video]: http://www.youtube.com/watch?v=xX96xng7sAE + +To complete this exercise you need to implement the function `isLeapYear` +that takes a year and determines whether it is a leap year. + +## Source + +### Created by + +- @etrepum + +### Contributed to by + +- @iHiD +- @karen-pal +- @kytrinyx +- @navossoc +- @paulrex +- @petertseng +- @ppartarr +- @rbasso +- @sshine +- @tejasbubane +- @tofische + +### Based on + +JavaRanch Cattle Drive, exercise 3 - http://www.javaranch.com/leap.jsp \ No newline at end of file diff --git a/haskell/leap/examples/error-nosig/package.yaml b/haskell/leap/examples/error-nosig/package.yaml new file mode 100644 index 0000000..2c476e4 --- /dev/null +++ b/haskell/leap/examples/error-nosig/package.yaml @@ -0,0 +1,16 @@ +name: leap + +dependencies: + - base + +library: + exposed-modules: LeapYear + source-dirs: src + +tests: + test: + main: Tests.hs + source-dirs: test + dependencies: + - leap + - hspec diff --git a/haskell/leap/examples/error-nosig/src/LeapYear.hs b/haskell/leap/examples/error-nosig/src/LeapYear.hs new file mode 100644 index 0000000..b68e344 --- /dev/null +++ b/haskell/leap/examples/error-nosig/src/LeapYear.hs @@ -0,0 +1,4 @@ +module LeapYear (isLeapYear) where + +isLeapYear year = hasFactor 4 && (not (hasFactor 100) || hasFactor 400) + where hasFactor n = year `rem` n == 0 diff --git a/haskell/leap/examples/success-standard/package.yaml b/haskell/leap/examples/success-standard/package.yaml new file mode 100644 index 0000000..2c476e4 --- /dev/null +++ b/haskell/leap/examples/success-standard/package.yaml @@ -0,0 +1,16 @@ +name: leap + +dependencies: + - base + +library: + exposed-modules: LeapYear + source-dirs: src + +tests: + test: + main: Tests.hs + source-dirs: test + dependencies: + - leap + - hspec diff --git a/haskell/leap/package.yaml b/haskell/leap/package.yaml new file mode 100644 index 0000000..5364801 --- /dev/null +++ b/haskell/leap/package.yaml @@ -0,0 +1,21 @@ +name: leap +version: 1.6.0.10 + +dependencies: + - base + +library: + exposed-modules: LeapYear + 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: + - leap + - hspec diff --git a/haskell/leap/src/LeapYear.hs b/haskell/leap/src/LeapYear.hs new file mode 100644 index 0000000..e80781b --- /dev/null +++ b/haskell/leap/src/LeapYear.hs @@ -0,0 +1,4 @@ +module LeapYear (isLeapYear) where + +isLeapYear :: Integer -> Bool +isLeapYear year = year `mod` 4 == 0 && ((year `mod` 100 /= 0) || (year `mod` 400 == 0)) diff --git a/haskell/leap/stack.yaml b/haskell/leap/stack.yaml new file mode 100644 index 0000000..35c2e5b --- /dev/null +++ b/haskell/leap/stack.yaml @@ -0,0 +1 @@ +resolver: lts-16.21 diff --git a/haskell/leap/test/Tests.hs b/haskell/leap/test/Tests.hs new file mode 100644 index 0000000..a000cb1 --- /dev/null +++ b/haskell/leap/test/Tests.hs @@ -0,0 +1,66 @@ +{-# OPTIONS_GHC -fno-warn-type-defaults #-} +{-# LANGUAGE RecordWildCards #-} + +import Data.Foldable (for_) +import Test.Hspec (Spec, describe, it, shouldBe) +import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) + +import LeapYear (isLeapYear) + +main :: IO () +main = hspecWith defaultConfig {configFastFail = True} specs + +specs :: Spec +specs = describe "isLeapYear" $ for_ cases test + where + + test Case{..} = it explanation assertion + where + explanation = unwords [show input, "-", description] + assertion = isLeapYear (fromIntegral input) `shouldBe` expected + +data Case = Case { description :: String + , input :: Integer + , expected :: Bool + } + +cases :: [Case] +cases = [ Case { description = "year not divisible by 4 in common year" + , input = 2015 + , expected = False + } + , Case { description = "year divisible by 2, not divisible by 4 in common year" + , input = 1970 + , expected = False + } + , Case { description = "year divisible by 4, not divisible by 100 in leap year" + , input = 1996 + , expected = True + } + , Case { description = "year divisible by 4 and 5 is still a leap year" + , input = 1960 + , expected = True + } + , Case { description = "year divisible by 100, not divisible by 400 in common year" + , input = 2100 + , expected = False + } + , Case { description = "year divisible by 100 but not by 3 is still not a leap year" + , input = 1900 + , expected = False + } + , Case { description = "year divisible by 400 in leap year" + , input = 2000 + , expected = True + } + , Case { description = "year divisible by 400 but not by 125 is still a leap year" + , input = 2400 + , expected = True + } + , Case { description = "year divisible by 200, not divisible by 400 in common year" + , input = 1800 + , expected = False + } + ] + +-- bd7f470e9ffe40993fc49558a02676ac22827441