Skip to content

Instantly share code, notes, and snippets.

@edvardm
Last active March 19, 2018 15:17
Show Gist options
  • Save edvardm/66b7887f1785345be69c4af37f31375c to your computer and use it in GitHub Desktop.
Save edvardm/66b7887f1785345be69c4af37f31375c to your computer and use it in GitHub Desktop.
Bowling kata, haskell version
-- Credits to awesome Haskell Master Sami Hangaslammi (shangaslammi) who told to learn unfoldr, which
-- leads IMO to very elegant solution.
--
-- 2012: original version, Hspec outdated, no longer available
-- 2018-03-19: Updated to recent Hspec
-- Running: cabal install hspec-2.4.4 && runhaskell bowling.hs
import Test.Hspec
import Data.List (unfoldr)
bowlingScore :: [Char] -> Int
bowlingScore = sum . frameScores where
frameScores pins = take 10 $ unfoldr frame pins
frame pins = case pins of
[] -> Nothing
('X':xs) -> Just (10 + sumRolls 2 xs, xs)
(_:'/':xs) -> Just (10 + sumRolls 1 xs, xs)
(p:'-':xs) -> Just (rollScore p, xs)
(p:q:xs) -> Just (rollScore p + rollScore q, xs)
(p:_) -> Just (rollScore p, [])
sumRolls count = sum . map rollScore . take count
rollScore 'X' = 10
rollScore '-' = 0
rollScore p = read [p] :: Int
main :: IO ()
main = hspec $
describe "bowlingScore" $ do
it "scores hits and misses" $ do
bowlingScore "9-9-9-9-9-9-9-9-9-9-" `shouldBe` 90
it "scores game with no gutters but no spares or strikes" $ do
bowlingScore "42424242424242424242" `shouldBe` 60
it "scores spares" $ do
bowlingScore "9/9/9/9/919-9-9-9-9-" `shouldBe` 4*19 + 1 + 6*9
it "scores unfinished games" $ do
bowlingScore "X5-3/X" `shouldBe` 15 + 5 + 10 + 10 + 10
it "scores single round" $ do
bowlingScore "5" `shouldBe` 5
it "scores odd number of rounds" $ do
bowlingScore "-29" `shouldBe` 11
it "scores perfect round" $ do
bowlingScore (replicate 12 'X') `shouldBe` 300
@edvardm
Copy link
Author

edvardm commented Mar 19, 2018

  • Updated for recent Hspec
  • Added test for odd number of rolls
  • Removed extra fluff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment