# paulfioravanti's solution

## to Scrabble Score in the Elixir Track

Published at Jun 24 2019 · 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 tests

Execute the tests with:

\$ mix test

### Pending tests

In the test suites, all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by commenting out the relevant @tag :pending with a # symbol.

For example:

# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end

Or, you can enable all the tests by commenting out the ExUnit.configure line in the test suite.

# ExUnit.configure exclude: :pending, trace: true

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

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

### scrabble_test.exs

defmodule ScrabbleTest do
use ExUnit.Case

# @tag :pending
test "empty word scores zero" do
assert Scrabble.score("") == 0
end

@tag :pending
test "whitespace scores zero" do
assert Scrabble.score(" \t\n") == 0
end

@tag :pending
test "scores very short word" do
assert Scrabble.score("a") == 1
end

@tag :pending
test "scores other very short word" do
assert Scrabble.score("f") == 4
end

@tag :pending
test "simple word scores the number of letters" do
assert Scrabble.score("street") == 6
end

@tag :pending
test "complicated word scores more" do
assert Scrabble.score("quirky") == 22
end

@tag :pending
test "scores are case insensitive" do
assert Scrabble.score("OXYPHENBUTAZONE") == 41
end

@tag :pending
test "convenient scoring" do
assert Scrabble.score("alacrity") == 13
end
end

### test_helper.exs

ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)
defmodule Scrabble do
@one_point_letters 'aeioulnrst'
@two_point_letters 'dg'
@three_point_letters 'bcmp'
@four_point_letters 'fhvwy'
@five_point_letters 'k'
@eight_point_letters 'jx'
@ten_point_letters 'qz'

defguardp one_point(letter) when letter in @one_point_letters
defguardp two_points(letter) when letter in @two_point_letters
defguardp three_points(letter) when letter in @three_point_letters
defguardp four_points(letter) when letter in @four_point_letters
defguardp five_points(letter) when letter in @five_point_letters
defguardp eight_points(letter) when letter in @eight_point_letters
defguardp ten_points(letter) when letter in @ten_point_letters

@doc """
Calculate the scrabble score for the word.
"""
@spec score(String.t()) :: non_neg_integer
def score(word) do
word
|> String.downcase()
|> String.to_charlist()
end

defp add_score_for_letter(letter, acc) when one_point(letter), do: acc + 1
defp add_score_for_letter(letter, acc) when two_points(letter), do: acc + 2
defp add_score_for_letter(letter, acc) when three_points(letter), do: acc + 3
defp add_score_for_letter(letter, acc) when four_points(letter), do: acc + 4
defp add_score_for_letter(letter, acc) when five_points(letter), do: acc + 5
defp add_score_for_letter(letter, acc) when eight_points(letter), do: acc + 8
defp add_score_for_letter(letter, acc) when ten_points(letter), do: acc + 10
end