Skip to content

Commit d923090

Browse files
meatball133BethanyG
authored andcommitted
Started
1 parent 759ec3f commit d923090

File tree

10 files changed

+326
-0
lines changed

10 files changed

+326
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Dictionary
2+
3+
```python
4+
LETTER_SCORES = {
5+
'A': 1,
6+
'E': 1,
7+
'I': 1,
8+
'O': 1,
9+
'U': 1,
10+
'L': 1,
11+
'N': 1,
12+
'R': 1,
13+
'S': 1,
14+
'T': 1,
15+
'D': 2,
16+
'G': 2,
17+
'B': 3,
18+
'C': 3,
19+
'M': 3,
20+
'P': 3,
21+
'F': 4,
22+
'H': 4,
23+
'V': 4,
24+
'W': 4,
25+
'Y': 4,
26+
'K': 5,
27+
'J': 8,
28+
'X': 8,
29+
'Q': 10,
30+
'Z': 10
31+
}
32+
33+
def score(word):
34+
return sum(LETTER_SCORES[letter.upper()] for letter in word)
35+
```
36+
37+
The code starts with initializing a constant that is a [dictionary][dictionary] that holds all the letters as different key and their respective score as a value.
38+
Then it defines a function that takes a word as an argument.
39+
40+
The function returns the built in function [`sum`][sum] that takes a [generator expression][generator-expersion] that iterates over the letters in the word.
41+
What a generator expression does is that it generates the values on the fly.
42+
Meaning that it doesn't have to use a lot of memory since it uses the last value and generates the next value.
43+
44+
Under the generation a letter is given from the string, then it is converted to upcase, and then being looked up at inside of the dictionary and the value is returned.
45+
46+
There is also a very similar approach that uses a dictionary transposition.
47+
Although that approach requires more computational calculation therefore is this approach more efficient.
48+
49+
[dictionary]: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
50+
[generator-expersion]: https://peps.python.org/pep-0289/
51+
[sum]: https://docs.python.org/3/library/functions.html#sum
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def score(word):
2+
return sum(LETTER_SCORES[letter.upper()] for letter in word)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Enum
2+
3+
```python
4+
from enum import IntEnum
5+
6+
class Scrabble(IntEnum):
7+
A = E = I = O = U = L = N = R = S = T = 1
8+
D = G = 2
9+
B = C = M = P = 3
10+
F = H = V = W = Y = 4
11+
K = 5
12+
J = X = 8
13+
Q = Z = 10
14+
15+
def score(word):
16+
return sum(Scrabble[char.upper()] for char in word)
17+
```
18+
19+
This approach uses an [`enum`][enum] to define the score of each letter.
20+
An `enum` or known as a enumerations is sets of named constant and is immutable.
21+
`enum` was added to python standard library also known as stdlib in python 3.4.
22+
23+
This approach uses an [`intEnum`][int-enum] it works very similar to a normal `enum` but it has the added benefit that the values are integers.
24+
Thereby acts like integers.
25+
26+
To use an `intEnum` you need to [import][import] it using: `from enum import IntEnum`.
27+
Then you can define the `enum` class.
28+
29+
The `enum` class is defined by using the [`class`][classes] keyword.
30+
Then you need to specify the name of the class.
31+
32+
After that is constant declared by giving the constant capital letters and the value is assigned by using the `=` operator.
33+
This approach works by giving all the letters as constants and then value of the constant is the score of the letter.
34+
After the `enum` is defined, the `score` function is defined.
35+
36+
The `score` function takes a word as a parameter.
37+
And uses the same [generator expression][generator-expersion] as the [dictionary approach][dictionary-approach].
38+
But instead of looking up the value in a dictionary it looks it up in the `enum` class.
39+
40+
[classes]: https://docs.python.org/3/tutorial/classes.html
41+
[enum]: https://docs.python.org/3/library/enum.html
42+
[generator-expersion]: https://peps.python.org/pep-0289/
43+
[int-enum]: https://docs.python.org/3/library/enum.html#enum.IntEnum
44+
[import]: https://docs.python.org/3/reference/import.html
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class Scrabble(IntEnum):
2+
A = E = I = O = U = L = N = R = S = T = 1
3+
D = G = 2
4+
B = C = M = P = 3
5+
F = H = V = W = Y = 4
6+
K = 5
7+
J = X = 8
8+
Q = Z = 10
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"introduction": {
3+
"authors": ["meatball133", "bethanyg"],
4+
"contributors": []
5+
},
6+
"approaches": [
7+
{
8+
"uuid": "62f556c0-27a6-43e5-80ea-d7abd921f0e7",
9+
"slug": "enum",
10+
"title": "Enum",
11+
"blurb": "Define a enum to solve the problem",
12+
"authors": ["meatball133", "bethanyg"]
13+
},
14+
{
15+
"uuid": "21c0fe14-585f-4e14-9f31-1d294a8a622c",
16+
"slug": "dictionary",
17+
"title": "Dictionary",
18+
"blurb": "Dictionary approach",
19+
"authors": ["meatball133", "bethanyg"]
20+
},
21+
{
22+
"uuid": "34911050-b424-4289-9d3f-aa5f0e8f1630",
23+
"slug": "nested-tuple",
24+
"title": "Nested Tuple",
25+
"blurb": "Nested Tuple approach",
26+
"authors": ["meatball133", "bethanyg"]
27+
},
28+
{
29+
"uuid": "e9b8e10b-23c7-4c2a-afbe-3c3499468919",
30+
"slug": "two-sequences",
31+
"title": "Two Sequences",
32+
"blurb": "Two Sequences approach",
33+
"authors": ["meatball133", "bethanyg"]
34+
}
35+
]
36+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Introduction
2+
3+
There are various ways to solve `scrabble-score`.
4+
This approaches document shows different strategies to solve this exercise
5+
6+
## General guidance
7+
8+
The goal of this exercise is to write a function that calculates the scrabble score for a given word.
9+
The problem is that
10+
11+
## Approach: Using a single dictionary
12+
13+
Using a single dictionary is an approach, it is simple and fast.
14+
It is also very pythonic.
15+
16+
```python
17+
LETTER_SCORES = {
18+
'A': 1,
19+
'E': 1,
20+
'I': 1,
21+
'O': 1,
22+
'U': 1,
23+
'L': 1,
24+
'N': 1,
25+
'R': 1,
26+
'S': 1,
27+
'T': 1,
28+
'D': 2,
29+
'G': 2,
30+
'B': 3,
31+
'C': 3,
32+
'M': 3,
33+
'P': 3,
34+
'F': 4,
35+
'H': 4,
36+
'V': 4,
37+
'W': 4,
38+
'Y': 4,
39+
'K': 5,
40+
'J': 8,
41+
'X': 8,
42+
'Q': 10,
43+
'Z': 10
44+
}
45+
46+
def score(word):
47+
return sum(LETTER_SCORES[letter.upper()] for letter in word)
48+
```
49+
50+
For more information, check the [Dictionary Approach][dictionary-approach].
51+
52+
## Approach: Using two sequences
53+
54+
Using two sequences is an approach, it is fast.
55+
Although the reason you might not want to do this is that it is hard to read.
56+
57+
```python
58+
KEYS = "AEIOULNRSTDGBCMPFHVWYKJXQZ"
59+
SCORES = [1] * 10 + [2] * 2 + [3] * 4 + [4] * 5 + [5] * 1 + [8] * 2 +[10] * 2
60+
61+
def score(word):
62+
return sum(SCORES[KEYS.index(letter.upper())] for letter in word)
63+
```
64+
65+
For more information, check the [Two Sequences Approach][two-sequences-approach].
66+
67+
## Approach: Enum
68+
69+
Using an `enum` is an approach, it is short and easy to read.
70+
Although it is more complicated since it uses a class.
71+
72+
```python
73+
from enum import IntEnum
74+
75+
class Scrabble(IntEnum):
76+
A = E = I = O = U = L = N = R = S = T = 1
77+
D = G = 2
78+
B = C = M = P = 3
79+
F = H = V = W = Y = 4
80+
K = 5
81+
J = X = 8
82+
Q = Z = 10
83+
84+
def score(word):
85+
return sum(Scrabble[char.upper()] for char in word)
86+
```
87+
88+
You can read more about how to achieve this optimization in: [Enum Approach][enum-approach].
89+
90+
## Approach: Using a nested tuple
91+
92+
Tuples in python is more memory efficent than using a dictonary in python.
93+
Although this solution since it is iterating over a tuple for every letter so is it slower.
94+
95+
```python
96+
LETTERS_OF_SCORE = (
97+
("AEIOULNRST", 1),
98+
("DG", 2),
99+
("BCMP", 3),
100+
("FHVWY", 4),
101+
("K", 5),
102+
("JX", 8),
103+
("QZ", 10),
104+
)
105+
106+
def score(word):
107+
return sum(for character in word for letters, score in LETTERS_OF_SCORE if character in letters)
108+
```
109+
110+
For more information, check the [Nested Tuple Approach][nested-tuple-approach].
111+
112+
[dictionary-approach]: https://exercism.org/tracks/python/exercises/scrabble-score/approaches/dictionary
113+
[enum-approach]: https://exercism.org/tracks/python/exercises/scrabble-score/approaches/enum
114+
[nested-tuple-approach]: https://exercism.org/tracks/python/exercises/scrabble-score/approaches/nested-tuple
115+
[two-sequences-approach]: https://exercism.org/tracks/python/exercises/scrabble-score/approaches/two-sequences
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Nested Tuple
2+
3+
```python
4+
LETTERS_OF_SCORE = (
5+
("AEIOULNRST", 1),
6+
("DG", 2),
7+
("BCMP", 3),
8+
("FHVWY", 4),
9+
("K", 5),
10+
("JX", 8),
11+
("QZ", 10),
12+
)
13+
14+
def score(word):
15+
return sum(score for character in word for letters, score in LETTERS_OF_SCORE if character.upper() in letters)
16+
```
17+
18+
The code starts with initializing a constant with a [tuple][tuple] of tuples.
19+
Inside of the inner tuples there is 2 values, the first value is a string of letters and the second value is the score of the letters.
20+
21+
Then it defines a function that takes a word as an argument.
22+
The function returns a [generator expression][generator-expersion] similar to the [dictionary approach][dictionary-approach].
23+
The difference is that it uses a nested [for loop][for-loop] to iterate over the letters and the tuples.
24+
There we iterate over the characters in the word and then iterate over the tuples.
25+
There the tuple is unpacked into the letters and the score.
26+
You can read more about unpacking in the [concept:python/unpacking-and-multiple-assignment]().
27+
28+
Then we check if the character is in the letters and if it is we return the score.
29+
30+
[tuple]: https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences
31+
[generator-expersion]: https://peps.python.org/pep-0289/
32+
[for-loop]: https://realpython.com/python-for-loop/
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
LETTERS_OF_SCORE = (
2+
("AEIOULNRST", 1),
3+
("DG", 2),
4+
("BCMP", 3),
5+
("FHVWY", 4),
6+
("K", 5),
7+
("JX", 8),
8+
("QZ", 10),)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Two sequences
2+
3+
```python
4+
KEYS = "AEIOULNRSTDGBCMPFHVWYKJXQZ"
5+
SCORES = [1] * 10 + [2] * 2 + [3] * 4 + [4] * 5 + [5] * 1 + [8] * 2 + [10] * 2
6+
7+
def score(word):
8+
return sum(SCORES[KEYS.index(letter.upper())] for letter in word)
9+
```
10+
11+
This approach uses a string and a [list][list], both of these data types belongs to the data type [sequences][sequence].
12+
It has a constant with a string with letters and then it has a constant of a list with corresponding score for the same index as the string.
13+
14+
The `score` function takes a word as a parameter.
15+
And uses the same [generator expression][generator-expersion] as the [dictionary approach][dictionary-approach].
16+
17+
The difference is that instead of using a [dictionary][dictionary] and looked up the score inside.
18+
This approach gets the index of the letter in the KEYS constant and then then looks up the value for that index in SCORES list.
19+
Then takes that value and return that to the generator expression.
20+
21+
[dictionary]: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
22+
[dictionary-approach]: https://exercism.org/tracks/python/exercises/scrabble-score/approaches/dictionary
23+
[list]: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
24+
[sequence]: https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
25+
[generator-expersion]: https://peps.python.org/pep-0289/
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
KEYS = "AEIOULNRSTDGBCMPFHVWYKJXQZ"
2+
SCORES = [1] * 10 + [2] * 2 + [3] * 4 + [4] * 5 + [5] * 1 + [8] * 2 +[10] * 2
3+
4+
def score(word):
5+
return sum(SCORES[KEYS.index(letter.upper())] for letter in word)

0 commit comments

Comments
 (0)