Skip to content

Commit d61b984

Browse files
committed
Add sum-of-multiples example
1 parent f0f3388 commit d61b984

File tree

7 files changed

+261
-0
lines changed

7 files changed

+261
-0
lines changed

sum-of-multiples/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Sum Of Multiples
2+
3+
Given a number, find the sum of all the unique multiples of particular numbers up to
4+
but not including that number.
5+
6+
If we list all the natural numbers below 20 that are multiples of 3 or 5,
7+
we get 3, 5, 6, 9, 10, 12, 15, and 18.
8+
9+
The sum of these multiples is 78.
10+
11+
12+
## Getting Started
13+
14+
Please refer to the [installation](https://exercism.io/tracks/haskell/installation)
15+
and [learning](https://exercism.io/tracks/haskell/learning) help pages.
16+
17+
## Running the tests
18+
19+
To run the test suite, execute the following command:
20+
21+
```bash
22+
stack test
23+
```
24+
25+
#### If you get an error message like this...
26+
27+
```
28+
No .cabal file found in directory
29+
```
30+
31+
You are probably running an old stack version and need
32+
to upgrade it.
33+
34+
#### Otherwise, if you get an error message like this...
35+
36+
```
37+
No compiler found, expected minor version match with...
38+
Try running "stack setup" to install the correct GHC...
39+
```
40+
41+
Just do as it says and it will download and install
42+
the correct compiler version:
43+
44+
```bash
45+
stack setup
46+
```
47+
48+
## Running *GHCi*
49+
50+
If you want to play with your solution in GHCi, just run the command:
51+
52+
```bash
53+
stack ghci
54+
```
55+
56+
## Feedback, Issues, Pull Requests
57+
58+
The [exercism/haskell](https://github.com/exercism/haskell) repository on
59+
GitHub is the home for all of the Haskell exercises.
60+
61+
If you have feedback about an exercise, or want to help implementing a new
62+
one, head over there and create an issue. We'll do our best to help you!
63+
64+
## Source
65+
66+
A variation on Problem 1 at Project Euler [http://projecteuler.net/problem=1](http://projecteuler.net/problem=1)
67+
68+
## Submitting Incomplete Solutions
69+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

sum-of-multiples/package.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: sum-of-multiples
2+
version: 1.5.0.10
3+
4+
dependencies:
5+
- base
6+
7+
library:
8+
exposed-modules: SumOfMultiples
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+
- sum-of-multiples
21+
- hspec
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module SumOfMultiples (sumOfMultiples) where
2+
3+
sumOfMultiples :: [Integer] -> Integer -> Integer
4+
sumOfMultiples factors limit = multiples (limit-1)
5+
where
6+
factors' = [f | f <- factors, f>0]
7+
anyFactors n = any (\f -> (rem n f) == 0) factors'
8+
multiples l
9+
| l>0 && anyFactors l = l + multiples (l-1)
10+
| l>0 = multiples (l-1)
11+
| otherwise = 0
12+

sum-of-multiples/stack.yaml

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

sum-of-multiples/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
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: af1be49874642abc6b07ca1898722e7c6220dbf1d18092102a163446f2b7490d
8+
9+
name: sum-of-multiples
10+
version: 1.5.0.10
11+
build-type: Simple
12+
13+
library
14+
exposed-modules:
15+
SumOfMultiples
16+
other-modules:
17+
Paths_sum_of_multiples
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_sum_of_multiples
30+
hs-source-dirs:
31+
test
32+
build-depends:
33+
base
34+
, hspec
35+
, sum-of-multiples
36+
default-language: Haskell2010

sum-of-multiples/test/Tests.hs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
2+
{-# LANGUAGE RecordWildCards #-}
3+
4+
import Data.Foldable (for_)
5+
import Test.Hspec (Spec, describe, it, shouldBe)
6+
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)
7+
8+
import SumOfMultiples (sumOfMultiples)
9+
10+
main :: IO ()
11+
main = hspecWith defaultConfig {configFastFail = True} specs
12+
13+
specs :: Spec
14+
specs = describe "sumOfMultiples" $ for_ cases test
15+
where
16+
test Case{..} = it description' assertion
17+
where
18+
description' = unwords [show factors, show limit, "--", description]
19+
assertion = expression `shouldBe` fromIntegral expected
20+
expression = sumOfMultiples (fromIntegral <$> factors)
21+
(fromIntegral limit )
22+
23+
data Case = Case { factors :: [Integer]
24+
, limit :: Integer
25+
, expected :: Integer
26+
, description :: String
27+
}
28+
29+
cases :: [Case]
30+
cases = [ Case { factors = [3, 5]
31+
, limit = 1
32+
, expected = 0
33+
, description = "no multiples within limit"
34+
}
35+
, Case { factors = [3, 5]
36+
, limit = 4
37+
, expected = 3
38+
, description = "one factor has multiples within limit"
39+
}
40+
, Case { factors = [3]
41+
, limit = 7
42+
, expected = 9
43+
, description = "more than one multiple within limit"
44+
}
45+
, Case { factors = [3, 5]
46+
, limit = 10
47+
, expected = 23
48+
, description = "more than one factor with multiples within limit"
49+
}
50+
, Case { factors = [3, 5]
51+
, limit = 100
52+
, expected = 2318
53+
, description = "each multiple is only counted once"
54+
}
55+
, Case { factors = [3, 5]
56+
, limit = 1000
57+
, expected = 233168
58+
, description = "a much larger limit"
59+
}
60+
, Case { factors = [7, 13, 17]
61+
, limit = 20
62+
, expected = 51
63+
, description = "three factors"
64+
}
65+
, Case { factors = [4, 6]
66+
, limit = 15
67+
, expected = 30
68+
, description = "factors not relatively prime"
69+
}
70+
, Case { factors = [5, 6, 8]
71+
, limit = 150
72+
, expected = 4419
73+
, description = "some pairs of factors relatively prime and some not"
74+
}
75+
, Case { factors = [5, 25]
76+
, limit = 51
77+
, expected = 275
78+
, description = "one factor is a multiple of another"
79+
}
80+
, Case { factors = [43, 47]
81+
, limit = 10000
82+
, expected = 2203160
83+
, description = "much larger factors"
84+
}
85+
, Case { factors = [1]
86+
, limit = 100
87+
, expected = 4950
88+
, description = "all numbers are multiples of 1"
89+
}
90+
, Case { factors = []
91+
, limit = 10000
92+
, expected = 0
93+
, description = "no factors means an empty sum"
94+
}
95+
, Case { factors = [0]
96+
, limit = 1
97+
, expected = 0
98+
, description = "the only multiple of 0 is 0"
99+
}
100+
, Case { factors = [3, 0]
101+
, limit = 4
102+
, expected = 3
103+
, description = "the factor 0 does not affect the sum of multiples of other factors"
104+
}
105+
, Case { factors = [2, 3, 5, 7, 11]
106+
, limit = 10000
107+
, expected = 39614537
108+
, description = "solutions using include-exclude must extend to cardinality greater than 3"
109+
}
110+
]

0 commit comments

Comments
 (0)