haskell: leap

This commit is contained in:
James Walker 2021-09-09 10:59:03 -04:00
parent 8fe30a1a00
commit b1ec5d6b16
Signed by: walkah
GPG Key ID: 3C127179D6086E93
9 changed files with 272 additions and 0 deletions

88
haskell/leap/HELP.md Normal file
View File

@ -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 }}

56
haskell/leap/README.md Normal file
View File

@ -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

View File

@ -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

View File

@ -0,0 +1,4 @@
module LeapYear (isLeapYear) where
isLeapYear year = hasFactor 4 && (not (hasFactor 100) || hasFactor 400)
where hasFactor n = year `rem` n == 0

View File

@ -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

21
haskell/leap/package.yaml Normal file
View File

@ -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

View File

@ -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))

1
haskell/leap/stack.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-16.21

View File

@ -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