Skip to content

Commit 84d65a7

Browse files
committed
Add Grains example
1 parent d61b984 commit 84d65a7

File tree

7 files changed

+214
-0
lines changed

7 files changed

+214
-0
lines changed

grains/README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Grains
2+
3+
Calculate the number of grains of wheat on a chessboard given that the number
4+
on each square doubles.
5+
6+
There once was a wise servant who saved the life of a prince. The king
7+
promised to pay whatever the servant could dream up. Knowing that the
8+
king loved chess, the servant told the king he would like to have grains
9+
of wheat. One grain on the first square of a chess board, with the number
10+
of grains doubling on each successive square.
11+
12+
There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on).
13+
14+
Write code that shows:
15+
- how many grains were on a given square, and
16+
- the total number of grains on the chessboard
17+
18+
## For bonus points
19+
20+
Did you get the tests passing and the code clean? If you want to, these
21+
are some additional things you could try:
22+
23+
- Optimize for speed.
24+
- Optimize for readability.
25+
26+
Then please share your thoughts in a comment on the submission. Did this
27+
experiment make the code better? Worse? Did you learn anything from it?
28+
29+
30+
## Getting Started
31+
32+
Please refer to the [installation](https://exercism.io/tracks/haskell/installation)
33+
and [learning](https://exercism.io/tracks/haskell/learning) help pages.
34+
35+
## Running the tests
36+
37+
To run the test suite, execute the following command:
38+
39+
```bash
40+
stack test
41+
```
42+
43+
#### If you get an error message like this...
44+
45+
```
46+
No .cabal file found in directory
47+
```
48+
49+
You are probably running an old stack version and need
50+
to upgrade it.
51+
52+
#### Otherwise, if you get an error message like this...
53+
54+
```
55+
No compiler found, expected minor version match with...
56+
Try running "stack setup" to install the correct GHC...
57+
```
58+
59+
Just do as it says and it will download and install
60+
the correct compiler version:
61+
62+
```bash
63+
stack setup
64+
```
65+
66+
## Running *GHCi*
67+
68+
If you want to play with your solution in GHCi, just run the command:
69+
70+
```bash
71+
stack ghci
72+
```
73+
74+
## Feedback, Issues, Pull Requests
75+
76+
The [exercism/haskell](https://github.com/exercism/haskell) repository on
77+
GitHub is the home for all of the Haskell exercises.
78+
79+
If you have feedback about an exercise, or want to help implementing a new
80+
one, head over there and create an issue. We'll do our best to help you!
81+
82+
## Source
83+
84+
JavaRanch Cattle Drive, exercise 6 [http://www.javaranch.com/grains.jsp](http://www.javaranch.com/grains.jsp)
85+
86+
## Submitting Incomplete Solutions
87+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

grains/grains.cabal

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
cabal-version: 1.12
2+
3+
-- This file has been generated from package.yaml by hpack version 0.33.0.
4+
--
5+
-- see: https://github.com/sol/hpack
6+
--
7+
-- hash: 88f82193be09582c3e69242198a92f693c1cd8ea6328c5dd88f0438ebd446d54
8+
9+
name: grains
10+
version: 1.2.0.6
11+
build-type: Simple
12+
13+
library
14+
exposed-modules:
15+
Grains
16+
other-modules:
17+
Paths_grains
18+
hs-source-dirs:
19+
src
20+
ghc-options: -Wall
21+
build-depends:
22+
base
23+
default-language: Haskell2010
24+
25+
test-suite test
26+
type: exitcode-stdio-1.0
27+
main-is: Tests.hs
28+
other-modules:
29+
Paths_grains
30+
hs-source-dirs:
31+
test
32+
build-depends:
33+
base
34+
, grains
35+
, hspec
36+
default-language: Haskell2010

grains/package.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: grains
2+
version: 1.2.0.6
3+
4+
dependencies:
5+
- base
6+
7+
library:
8+
exposed-modules: Grains
9+
source-dirs: src
10+
ghc-options: -Wall
11+
# dependencies:
12+
# - foo # List here the packages you
13+
# - bar # want to use in your solution.
14+
15+
tests:
16+
test:
17+
main: Tests.hs
18+
source-dirs: test
19+
dependencies:
20+
- grains
21+
- hspec

grains/src/Grains.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module Grains (square, total) where
2+
3+
square' :: Integer -> Integer
4+
square' n
5+
| n > 1 = 2 * square' (n-1)
6+
| otherwise = 1
7+
8+
square :: Integer -> Maybe Integer
9+
square n
10+
| n > 64 || n < 1 = Nothing
11+
| otherwise = Just (square' n)
12+
13+
14+
total :: Integer
15+
-- 2^0 + 2^1 + 2^2 .. + 2^63 = 2^64 - 1
16+
total = (2 * square' 64) - 1

grains/stack.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
resolver: lts-15.8

grains/stack.yaml.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# This file was autogenerated by Stack.
2+
# You should not edit this file by hand.
3+
# For more information, please see the documentation at:
4+
# https://docs.haskellstack.org/en/stable/lock_files
5+
6+
packages: []
7+
snapshots:
8+
- completed:
9+
size: 492015
10+
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/15/8.yaml
11+
sha256: 926bc3d70249dd0ba05277ff00943c0addb35b627cb641752669e7cf771310d0
12+
original: lts-15.8

grains/test/Tests.hs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
2+
3+
import Data.Foldable (for_)
4+
import Test.Hspec (Spec, describe, it, shouldBe)
5+
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)
6+
7+
import Grains (square, total)
8+
9+
main :: IO ()
10+
main = hspecWith defaultConfig {configFastFail = True} specs
11+
12+
specs :: Spec
13+
specs = do
14+
describe "square" $ for_ squareCases squareTest
15+
describe "total" $ totalTest totalCase
16+
where
17+
18+
squareTest (description, n, expected) = it description assertion
19+
where
20+
assertion = expression `shouldBe` expected
21+
expression = fmap fromIntegral . square . fromIntegral $ n
22+
23+
totalTest (description, expected) = it description assertion
24+
where
25+
assertion = fromIntegral total `shouldBe` expected
26+
27+
squareCases :: [(String, Integer, Maybe Integer)]
28+
squareCases =
29+
[ ("square 1" , 1, Just 1)
30+
, ("square 2" , 2, Just 2)
31+
, ("square 3" , 3, Just 4)
32+
, ("square 4" , 4, Just 8)
33+
, ("square 16" , 16, Just 32768)
34+
, ("square 32" , 32, Just 2147483648)
35+
, ("square 64" , 64, Just 9223372036854775808)
36+
, ("square negative" , -1, Nothing )
37+
, ("square 0" , 0, Nothing )
38+
, ("square bigger than 64", 65, Nothing ) ]
39+
40+
totalCase :: (String, Integer)
41+
totalCase = ("total grains", 18446744073709551615)

0 commit comments

Comments
 (0)