Skip to content
This repository has been archived by the owner on Oct 8, 2022. It is now read-only.

Commit

Permalink
First kata - find the sum all multiples of 3 or 5 less than 1000
Browse files Browse the repository at this point in the history
Sixth solution.

A whole new approach was attempted here. We have removed the loop throughout every single number to check if it is a multiple of 3 ou 5 to a mathematical approach using 2 different formulaes.
1. the sum of the multiples 3 or 5 = sum of multiples of 3 + sum of multiples of 5 - sum of multiples of 3 * 5
2. the sum of multiples of 3 = ((n * (n + 1)) / 2) * d
    where n = 1000 / 3 (upper limit divided by the multiple)
                d = multiple (in this case 3)

with this solution we solve the performance issue of the previous solution by providing a constant-time solution.
previous solution = 1 operation per number (i.e 10^10 will cause the function to run 10^10 steps)
new solution = 3 operation per limit (1 to compute the sum of multiples of 3, 1 to compute the sum of multiples of 5, 1 to compute the sum of multiples of 3 * 5)
  • Loading branch information
ggarciajr committed Apr 4, 2011
1 parent e829d90 commit 1b69416
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 9 deletions.
9 changes: 2 additions & 7 deletions haskell/katas/01/FirstKata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,5 @@ module FirstKata (
fkSum
) where

fkSum :: Int -> [Int] -> Int
fkSum a [] = 0
fkSum a (b) = foldl (+) 0 (filter (\x -> isMultiple x b) [1..a])

isMultiple :: Int -> [Int] -> Bool
isMultiple a [] = False
isMultiple a (x:xs) = if (mod a x == 0) then True else isMultiple a xs
fkSum u x y = f x + f y - f (x * y)
where f d = let n = u `div` d in (n * (n + 1) `div` 2) * d
4 changes: 2 additions & 2 deletions haskell/test/01/FirstKataTest.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Test.HUnit
import FirstKata

testFkSumFirst = TestCase $ assertEqual "result should be 23" 23 (fkSum 9 [3,5])
testFkSumSecond = TestCase $ assertEqual "result should be 233168" 233168 (fkSum 999 [3,5])
testFkSumFirst = TestCase $ assertEqual "result should be 23" 23 (fkSum 9 3 5)
testFkSumSecond = TestCase $ assertEqual "result should be 233168" 233168 (fkSum 999 3 5)

suite = TestList [ testFkSumFirst, testFkSumSecond ]

0 comments on commit 1b69416

Please sign in to comment.