ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# mnkisala's solution

## to Scrabble Score in the Haskell Track

Published at Dec 20 2020 · 0 comments
Instructions
Test suite
Solution

Given a word, compute the Scrabble score for that word.

## Letter Values

You'll need these:

``````Letter                           Value
A, E, I, O, U, L, N, R, S, T       1
D, G                               2
B, C, M, P                         3
F, H, V, W, Y                      4
K                                  5
J, X                               8
Q, Z                               10
``````

## Examples

"cabbage" should be scored as worth 14 points:

• 3 points for C
• 1 point for A, twice
• 3 points for B, twice
• 2 points for G
• 1 point for E

And to total:

• `3 + 2*1 + 2*3 + 2 + 1`
• = `3 + 2 + 6 + 3`
• = `5 + 9`
• = 14

## Extensions

• You can play a double or a triple letter.
• You can play a double or a triple word.

## Getting Started

Please refer to the installation and learning help pages.

## Running the tests

To run the test suite, execute the following command:

``````stack test
``````

#### If you get an error message like this...

``````No .cabal file found in directory
``````

You are probably running an old stack version and need to upgrade it.

#### 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:

``````stack setup
``````

## Running GHCi

If you want to play with your solution in GHCi, just run the command:

``````stack ghci
``````

## Feedback, Issues, Pull Requests

The 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!

## Source

Inspired by the Extreme Startup game https://github.com/rchatley/extreme_startup

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### Tests.hs

``````{-# 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 Scrabble (scoreLetter, scoreWord)

main :: IO ()
main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = do
describe "scoreLetter" \$ do
it "'a'" \$ scoreLetter 'a' `shouldBe`  1
it "'Z'" \$ scoreLetter 'Z' `shouldBe` 10
it "'?'" \$ scoreLetter '?' `shouldBe`  0
describe "scoreWord" \$ for_ cases test
where

test Case{..} = it description assertion
where
assertion = scoreWord input `shouldBe` fromIntegral expected

data Case = Case { description :: String
, input       :: String
, expected    :: Integer
}

cases :: [Case]
cases = [ Case { description = "lowercase letter"
, input       = "a"
, expected    = 1
}
, Case { description = "uppercase letter"
, input       = "A"
, expected    = 1
}
, Case { description = "valuable letter"
, input       = "f"
, expected    = 4
}
, Case { description = "short word"
, input       = "at"
, expected    = 2
}
, Case { description = "short, valuable word"
, input       = "zoo"
, expected    = 12
}
, Case { description = "medium word"
, input       = "street"
, expected    = 6
}
, Case { description = "medium, valuable word"
, input       = "quirky"
, expected    = 22
}
, Case { description = "long, mixed-case word"
, input       = "OxyphenButazone"
, expected    = 41
}
, Case { description = "english-like word"
, input       = "pinata"
, expected    = 8
}
, Case { description = "empty input"
, input       = ""
, expected    = 0
}
, Case { description = "entire alphabet available"
, input       = "abcdefghijklmnopqrstuvwxyz"
, expected    = 87
}
]

-- a0aa908486542f98a0e421ed775f18945317506e``````
``````module Scrabble (scoreLetter, scoreWord) where

import Data.Char (toUpper)

scoreWord :: String -> Integer
scoreWord = sum . map scoreLetter

scoreLetter :: Char -> Integer
scoreLetter letter = sum \$ map f scoreLookup
where
f (letters, score) = if (toUpper letter) `elem` letters then score else 0

scoreLookup :: [([Char], Integer)]
scoreLookup = [
(['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'],  1),
(['D', 'G'], 2),
(['B', 'C', 'M', 'P'], 3),
(['F', 'H', 'V', 'W', 'Y'], 4),
(['K'], 5),
(['J', 'X'], 8),
(['Q', 'Z'], 10)
]``````