Problem:
Write a program that, given a word, computes the scrabble score for that word.
Code:
import java.util.regex.Pattern;
import java.util.Optional;
import java.util.Map;
import java.util.HashMap;
public class Scrabble {
private static final Pattern WHITE_SPACE = Pattern.compile("\\s+");
private static final Map<String, Integer> SCRABBLE_SCORE_MAP = initMap();
private final String phrase;
private int score;
public Scrabble(String phrase) {
this.phrase = Optional.ofNullable(phrase).orElse("")
.replaceAll(WHITE_SPACE.toString(), "").toLowerCase();
score = calculate();
}
public int getScore() {
return score;
}
private int calculate() {
int score = 0;
if (phrase.isEmpty()) {
return score;
}
for (char chr : phrase.toCharArray()) {
for (String key : SCRABBLE_SCORE_MAP.keySet()) {
if (key.indexOf(chr) != -1) {
score += SCRABBLE_SCORE_MAP.get(key);
}
}
}
return score;
}
private static Map<String, Integer> initMap() {
Map<String, Integer> map = new HashMap<>();
map.put("aeioulnrst", 1);
map.put("dg", 2);
map.put("bcmp", 3);
map.put("fhvwy", 4);
map.put("k", 5);
map.put("jx", 8);
map.put("qz", 10);
return map;
}
}
Test Suite:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class ScrabbleScoreTest {
private String input;
private int expectedOutput;
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"", 0},
{" \t\n", 0},
{null, 0},
{"a", 1},
{"f", 4},
{"street", 6},
{"quirky", 22},
{"OXYPHENBUTAZONE", 41},
{"alacrity", 13},
});
}
public ScrabbleScoreTest(String input, int expectedOutput) {
this.input = input;
this.expectedOutput = expectedOutput;
}
@Test
public void test() {
Scrabble scrabble = new Scrabble(input);
assertEquals(expectedOutput, scrabble.getScore());
}
}
Design Discussion:
- Instead of doing same calculation again and again I cached the score.
HashMap
seem a fine choice to me since I needed to map letters to score.
Question:
Apart from OOP
and encapsulation
is there any scope for improvement in efficiency?
Ref: