Introduction
Scrabble is a word game where players place letter tiles on a board to form words.
Each letter has a value.
A word’s score is the sum of its letters’ values.
Instructions
Instructions
Your task is to compute a word’s Scrabble score by summing the values of its letters.
The letters are valued as follows:
| 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 |
For example, the word “cabbage” is worth 14 points:
- 3 points for C
- 1 point for A
- 3 points for B
- 3 points for B
- 1 point for A
- 2 points for G
- 1 point for E
Dig Deeper
map
Map
object ScrabbleScore {
private val compressedMap =
mapOf(
1 to listOf('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'),
2 to listOf('D', 'G'),
3 to listOf('B', 'C', 'M', 'P'),
4 to listOf('F', 'H', 'V', 'W', 'Y'),
5 to listOf('K'),
8 to listOf('J', 'X'),
10 to listOf('Q', 'Z')
)
private val lookup = mutableMapOf<Char, Int>()
init {
compressedMap.forEach { entry ->
entry.value.forEach { letter -> lookup.put(letter, entry.key) }
}
}
fun scoreWord(word: String) = word.sumOf { lookup.getValue(it.uppercaseChar()) }
}
An object declaration is used to define ScrabbleScore as essentially a singleton object instantiation of the class.
This is sufficient, since there is no object state that needs to change with each call of the scoreWord method.
A private val is defined to hold a Map.
The Map is constructed with the mapOf method, which is passed key/value pairs made by the to keyword
to associate the score key with its list of Char values.
This is less tedious then typing the Map with a letter key and its score value for all of the letters.
However, for an efficient lookup, we want a letter key with its score value, so the mutableMapOf method is used
to initialize the lookup map.
Inside an initializer block, two forEach loops are used for loading the lookup Map with the transformed key/values from the first Map.
(If you have solved the Etl exercise, then this will be familiar to you.)
Each key/value entry is passed into the lambda for the outer forEach.
The inner forEach is called on the list of Char values for the entry.
Each Char letter is passed into the lambda for the inner forEach, where the put method is used to create a new entry in the lookup Map,
with the letter as the key and the score as the value.
The scoreWord function is also a single-expression function, implemented with the sumOf aggregate operation on the input word.
The lambda of sumOf uses the it keyword to refer to the single Char parameter for the lambda, and passes that to the
getValue method of the Map to look up the score for the letter.
The function returns the result of calling sumOf, which is the sum of the scores for each of the characters in the word.
when
when
object ScrabbleScore {
private fun scoreLetter(c: Char) =
when (c.uppercaseChar()) {
'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
else -> 0
}
fun scoreWord(word: String) = word.sumOf { scoreLetter(it) }
}
An object declaration is used to define ScrabbleScore as essentially a singleton object instantiation of the class.
This is sufficient, since there is no object state that needs to change with each call of the scoreWord method.
The private method for scoring the letter is implemented by a when expression.
Although the function has multiple lines, it consists only of the one when expression, so it is defined using
single-expression function syntax, with the curly braces omitted and the return type inferred.
The scoreWord function is also a single-expression function, implemented with the sumOf aggregate operation on the input word.
The lambda of sumOf uses the it keyword to refer to the single Char parameter for the lambda, and passes that to the function
for scoring a letter.
The function returns the result of calling sumOf, which is the sum of the scores for each of the characters in the word.
Source: Exercism kotlin/scrabble-score