Scrabble is a word game in which two to four players score points by placing tiles — each bearing a single letter — onto a game board. The tiles must form words which, in crossword fashion, flow left to right in rows or downwards in columns. The words must be defined in a standard dictionary, or be present in specified reference works that provide a list of officially permissible words.
The game is played on a square board with a $$15 \times 15 = 225$$ grid of squares, each of which accommodates a single letter tile. The board is marked with "premium" squares, which multiply the number of points awarded: eight dark red "triple-word" squares, 17 pink "double-word" squares, of which one, the center square, is marked with a star or other symbol; 12 dark blue "triple-letter" squares, and 24 light blue "double-letter" squares.
In an English-language set, the game contains of 100 tiles, 98 of which are marked with a letter and a point value ranging from 1 to 10. The number of points of each lettered tile is based on the letter's frequency in standard English writing. Commonly used letters such as vowels are worth one point, while less common letters score higher, with Q and Z each worth 10 points. The game also has two blank tiles that are unmarked and carry no point value. The blank tiles can be used as substitutes for any letter. Once laid on the board, however, the choice is fixed. Other language sets use different letter set distributions with different point values.
Before the game starts, a resource (either a word list or a dictionary) is selected for the purpose of adjudicating any challenges during the game. The letter tiles are put in an opaque bag. Next, players decide the order in which they play. The normal approach is for players to each draw one tile: the player who picks the letter closest to the beginning of the alphabet goes first, with the blank tiles taking precedence over A's. At the beginning of the game, each player draws a fixed number of tiles from the bag and places them on his or her rack, concealed from the other player(s). On each turn, the player has three options:
pass, forfeiting the turn and scoring nothing
exchange one or more tiles for an equal number from the bag, scoring nothing
play at least one tile on the board, adding the value of all words formed to the player's cumulative score
A proper play uses one or more of the player's tiles to form a continuous string of letters that make a word (the play's "main word") on the board, reading either left-to-right or top-to-bottom. The main word must either use the letters of one or more previously played words or else have at least one of its tiles horizontally or vertically adjacent to an already played word. If any words other than the main word are formed by the play, they are scored as well, and are subject to the same criteria of acceptability.
A blank tile may represent any letter, and scores zero points, regardless of its placement or what letter it represents. But its placement on a double-word or triple-word square does cause the corresponding premium to be applied to the word(s) in which it is used. Once a blank tile is placed, it remains that letter for the rest of the game. The player then draws tiles from the bag to replenish his or her rack. If there are not enough tiles in the bag to do so, the player takes all the remaining tiles. The game ends when either one player plays every tile on his or her rack and there are no tiles remaining in the bag (regardless of the tiles on his or her opponent's rack) or at least six successive scoreless turns have occurred and either player decides to end the game.
A collection of letters is represented as a string (str), a list, a tuple or a set containing uppercase letters and underscores (_), where the underscores represent blanks in the game of Scrabble. Letters and underscores may occur several times.
A bag of letters is represented as a dictionary (dict) whose keys are uppercase letters and possibly also an underscore (again representing a blank). Each key is associated with a strictly positive integer (int) that indicates the number of occurrences of the letter (or blank) in the bag. Note that it is not allowed to associate the value zero with a letter or a blank. If a letter/blank does not occur in the bag, there is no corresponding key/value pair in the dictionary that represents the bag.
Your task:
Write a function fill that takes a collection of letters. The function must return a dictionary (dict) that represents a bag that was filled with the given letters.
Write a function description that takes a bag of letters. The function must return a new dictionary (dict) whose keys are the values (int) of the dictionary that represents the given bag. Each key $$n \in \mathbb{N}_0$$ must be mapped onto a set containing all letters (str) that occur $$n$$ times in the given bag.
Write a function remove that takes two arguments: i) a collection of letters and ii) a bag of letters. The function must remove all given letters from the given bag by updating the dictionary that represents the given bag. In case the given bag does not contain all given letters, the dictionary representing the bag may not be updated, and an AssertionError must be raised with the message not all letters are in the bag.
>>> bag = fill('IAMDIETINGIEATQUINCEJELLYLOTSOFGROUNDMAIZEGIVESVARIETYICOOKRHUBARBANDSODAWEEPANEWORPUTONEXTRAFLESH__')
>>> bag
{'A': 9, 'B': 2, 'C': 2, 'D': 4, 'E': 12, 'F': 2, 'G': 3, 'H': 2, 'I': 9, 'J': 1, 'K': 1, 'L': 4, 'M': 2, 'N': 6, 'O': 8, 'P': 2, 'Q': 1, 'R': 6, 'S': 4, 'T': 6, 'U': 4, 'V': 2, 'W': 2, 'X': 1, 'Y': 2, 'Z': 1, '_': 2}
>>> description(bag)
{1: {'J', 'K', 'Q', 'X', 'Z'}, 2: {'B', 'C', 'F', 'H', 'M', 'P', 'V', 'W', 'Y', '_'}, 3: {'G'}, 4: {'D', 'L', 'S', 'U'}, 6: {'N', 'R', 'T'}, 8: {'O'}, 9: {'A', 'I'}, 12: {'E'}}
>>> remove('AEERTYOXMCNB_S', bag)
>>> bag
{'A': 8, 'B': 1, 'C': 1, 'D': 4, 'E': 10, 'F': 2, 'G': 3, 'H': 2, 'I': 9, 'J': 1, 'K': 1, 'L': 4, 'M': 1, 'N': 5, 'O': 7, 'P': 2, 'Q': 1, 'R': 5, 'S': 3, 'T': 5, 'U': 4, 'V': 2, 'W': 2, 'Y': 1, 'Z': 1, '_': 1}
>>> description(bag)
{1: {'B', 'C', 'J', 'K', 'M', 'Q', 'Y', 'Z', '_'}, 2: {'F', 'H', 'P', 'V', 'W'}, 3: {'G', 'S'}, 4: {'D', 'L', 'U'}, 5: {'N', 'R', 'T'}, 7: {'O'}, 8: {'A'}, 9: {'I'}, 10: {'E'}}
>>> remove('XXX', bag)
Traceback (most recent call last):
AssertionError: not all letters are in the bag
In 1975 Phoebe Winch discovered that the 100 standard Scrabble tiles reveal a hidden message:
I AM DIETING. I EAT QUINCE JELLY. LOTS OF GROUND MAIZE GIVES VARIETY. I COOK RHUBARB AND SODA, WEEP ANEW, OR PUT ON EXTRA FLESH.
The question is how well this Scrabble diet works …