# fxn's solution

## to Scrabble Score in the Nim Track

Published at Nov 08 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.

## Running the tests

To compile and run the tests, just run the following in your exercise directory:

\$ nim c -r test_scrabble_score.nim

## Submitting Exercises

Note that, when trying to submit an exercise, make sure the solution is in the \$EXERCISM_WORKSPACE/nim/scrabble-score directory.

You can find your Exercism workspace by running exercism debug and looking for the line that starts with Exercises Directory.

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

### test_scrabble_score.nim

import unittest
import scrabble_score

suite "Scrabble Score":
test "lowercase letter":
check score("a") == 1

test "uppercase letter":
check score("A") == 1

test "valuable letter":
check score("f") == 4

test "short word":
check score("at") == 2

test "short, valuable word":
check score("zoo") == 12

test "medium word":
check score("street") == 6

test "medium, valuable word":
check score("quirky") == 22

test "long, mixed-case word":
check score("OxyphenButazone") == 41

test "english-like word":
check score("pinata") == 8

test "empty input":
check score("") == 0

test "entire alphabet available":
check score("abcdefghijklmnopqrstuvwxyz") == 87
import tables, sequtils, strutils, math

# This table is nice to ensure we copy the exercise correctly.
const
lettersByScore = {
1: @['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'],
2: @['D', 'G'],
3: @['B', 'C', 'M', 'P'],
4: @['F', 'H', 'V', 'W', 'Y'],
5: @['K'],
8: @['J', 'X'],
10: @['Q', 'Z']
}.toTable
ordA = ord('A')

func idx(upperCaseLetter: char): int = ord(upperCaseLetter) - ordA

# It is better to invert the table, though, to compute scores efficiently. An
# array is going to be more efficient than a table.
var scoreForLetter: array[ord('Z') - ordA + 1, int]
for score, letters in lettersByScore:
for letter in letters:
scoreForLetter[idx(letter)] = score

proc score(letter: char): int =
scoreForLetter[idx(letter.toUpperAscii)]

proc score*(word: string): int =
word.mapIt(score(it)).sum