Skip to content

Instantly share code, notes, and snippets.

@thisiswei
Last active December 19, 2015 02:49
Show Gist options
  • Save thisiswei/5886236 to your computer and use it in GitHub Desktop.
Save thisiswei/5886236 to your computer and use it in GitHub Desktop.
these codingbat from peter remind me CS212.
"""
In a series of exercises we will develop a program to find the highest-scoring
play on a Scrabble board. But we'll get there in small steps. In this exercise,
we will decide if it is legal to play a given word at a given start position on
a Scrabble board. To make things easier, in these first few exercises, the
board will consist of a single row, which will be represented as a list: a 1
indicates a blank square (later we will add 2, 3, etc. for double-and triple
letter scores), a '*' marks the start square at the center of the board, and a
capital letter indicates a letter already on the bjoard. Write
scrabble_legal_play(row, k, word) to return True if it is legal to play the
word in the row, starting at position k. A word is legal at a position k if (1)
the word does not go off the edge of the board; (2) the word does not bump into
any other letters at the end (that is, if you want to place the word 'CAT' on
the board '...DOG....', it is ok to place it like this: '...DOG.CAT' but not ok
like this: 'CATDOG....'); (3) the letters already on the board match up with
the letters in the word; (4) the word connects to at least one existing letter
on the board, or it covers the start square, '*'.
"""
def scrabble_test():
assert scrabble_legal_play([1, 1, 1, 1, 'O', 1, 1, 1], 0, 'HELLO') == True
assert scrabble_legal_play([1, 'E', 1, 1, 'O', 1, 1, 1], 0, 'HELLO') == True
assert scrabble_legal_play([1, 1, 1, 1, 'O', 1, 1, 1], 0, 'HELLO') == True
assert scrabble_legal_play([1, 'E', 1, 1, 'O', 1, 1, 1], 0, 'HELLO') == True
assert scrabble_legal_play([1, 'A', 1, 1, 'O', 1, 1, 1], 0, 'HELLO') == False
assert scrabble_legal_play([1, 'E', 1, 1, 'O', 1, 1, 1], 1, 'ELL') == False
assert scrabble_legal_play([1, 1, 1, 1, 'O', 1, 1, 1], 4, 'OARS') == True
assert scrabble_legal_play([1, 1, 1, 1, '*', 1, 1, 1], 4, 'OARS') == True
assert scrabble_legal_play([1, 1, 1, 1, '*', 1, 1, 1], 0, 'OARS') == False
assert scrabble_legal_play([1, 1, 1, 1, 'O', 1, 1, 1], 4, 'OTHER') == False
LETTERS = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
def scrabble_legal_play(row, k, word):
end = k + len(word)
new_row = row[k:end]
return (k >= 0 and end <= len(row)
and (k == 0 or row[k-1] not in LETTERS)
and (end == len(row) or row[end] not in LETTERS)
and all((sq not in LETTERS or sq == word[i]) for (i, sq) in enumerate(new_row))
and any((sq == '*' or sq in LETTERS) for sq in new_row))
"""
In this exercise (a continuation of the previous Scrabble exercise), you will
write scrabble_legal_rack_play(row, k, word, rack) to return True if the given
word fits in the row at position k, and can be made out of the letters in the
player's rack of letters (plus the letters already on the board). Note that you
must use at least one letter from the rack to make a play legal. """
def rack_test():
assert scrabble_legal_rack_play([1, 1, 1, 1, 'O', 1, 1, 1], 0, 'HELLO', 'EHLLORT') == True
assert scrabble_legal_rack_play([1, 'E', 1, 1, 'O', 1, 1, 1], 0, 'HELLO', 'EHLLORT') == True
assert scrabble_legal_rack_play([1, 'E', 1, 1, 'O', 1, 1, 1], 0, 'HELLO', 'EHLMORT') == False
assert scrabble_legal_rack_play([1, 1, 1, 1, 'O', 1, 1, 1], 0, 'HELLO', 'EHLLORT') == True
assert scrabble_legal_rack_play([1, 'E', 1, 1, 'O', 1, 1, 1], 0, 'HELLO', 'EHLLORT') == True
assert scrabble_legal_rack_play([1, 'E', 1, 1, 'O', 1, 1, 1], 0, 'HELLO', 'EHLMORT') == False
assert scrabble_legal_rack_play([1, 'A', 1, 1, 'O', 1, 1, 1], 0, 'HELLO', 'EHLLORT') == False
assert scrabble_legal_rack_play([1, 1, 1, 1, '*', 1, 1, 1], 0, 'HELLO', 'EHLLORT') == True
assert scrabble_legal_rack_play([1, 1, 1, 1, 'O', 1, 1, 1], 4, 'OARS', 'EHLLORT') == False
assert scrabble_legal_rack_play([1, 1, 1, 1, 'O', 1, 1, 1], 4, 'O', 'EHLLORT') == False
assert scrabble_legal_rack_play([1, 1, 1, 1, 'O', 1, 1, 1], 4, 'OTHER', 'EHLLORT') == False
def scrabble_legal_rack_play(row, k, word, rack):
placed = [i for i in row if i in LETTERS]
new_word = word
for i in placed:
new_word = new_word.replace(i, '', 1)
return (scrabble_legal_play(row, k, word)
and all(rack.count(w) >= new_word.count(w) for w in new_word)
and ''.join(placed) != word)
# peter norvig's solution
def scrabble_legal_rack_play(row, k, word, rack):
row_part = row[k:k+len(word)]
return scrabble_legal_play(row, k, word) and have_letters(rack, row_part, word)
def have_letters(rack, row_part, word):
"Are the letters in rack plus row_part enough to make word, and did we use at least one?"
used_one = False
for r,w in zip(row_part, word):
if r == w:
pass # letter already on board
elif w not in rack:
return False
else:
rack = rack.replace(w, '', 1)
used_one = True
return used_one
"""In this third Scrabble exercise, you will write scrabble_all_plays(row, rack)
to return a list of (k, word) pairs that represent all the possible plays that
can be made anywhere on the row, given a dictionary of possible words. Use
'sorted' to sort the result. Instead of using the full official Scrabble
dictionary, use the following (very) abridged list of words: """
dictionary = "HE HELL HELLO LOW OTHER HER THE THERE WELL ELL EL TEE TOE OX OXEN ZOO ZOOLOGY".split()
def play_test():
assert scrabble_all_plays([1, 1, 'W', 1, 'E', 1, 1, 'X'], 'EHLLORT') == [(0, 'LOW'), (4, 'EL'), (6, 'OX')]
assert scrabble_all_plays([1, 'T', 'O', 1, 1, 1, 'L', 1], 'EHWLORT') == [(1, 'TOE'), (4, 'ELL'), (4, 'HELL'), (4, 'WELL'), (5, 'EL'), (5, 'ELL')]
assert scrabble_all_plays([1, 'E', 1, 1, 'O', 1, 1, 1], 'EHLLORT') == [(0, 'HE'), (0, 'HELLO'), (0, 'HER'), (0, 'TEE'), (1, 'EL'), (3, 'TOE')]
assert scrabble_all_plays([1, 1, 'W', 1, 'E', 1, 1, 'X'], 'EHLLORT') == [(0, 'LOW'), (4, 'EL'), (6, 'OX')]
assert scrabble_all_plays([1, 'T', 'O', 1, 1, 1, 'L', 1], 'EHWLORT') == [(1, 'TOE'), (4, 'ELL'), (4, 'HELL'), (4, 'WELL'), (5, 'EL'), (5, 'ELL')]
assert scrabble_all_plays([1, 'E', 1, 1, 'O', 1, 1, 1], 'EHLLORT') == [(0, 'HE'), (0, 'HELLO'), (0, 'HER'), (0, 'TEE'), (1, 'EL'), (3, 'TOE')]
assert scrabble_all_plays([1, 1, 1, 1, 'T', 1, 1, 1], 'EHLLORT') == [(3, 'OTHER'), (4, 'THE'), (4, 'TOE')]
assert scrabble_all_plays([1, 1, 1, 'T', 'O', 1, 1, 1], 'EHLLORT') == [(3, 'TOE')]
assert scrabble_all_plays([1, 1, 1, 'T', 'O', 'E', 1, 1], 'EHLLORT') == []
assert scrabble_all_plays([1, 'E', 1, 1, 'O', 1, 1, 1], 'EHNZXOT') == [(0, 'HE'), (0, 'TEE'), (3, 'TOE'), (3, 'ZOO'), (4, 'OX'), (4, 'OXEN')]
def scrabble_all_plays(row, rack):
return sorted((pos, word) for pos in range(len(row))
for word in dictionary
if scrabble_legal_rack_play(row, pos, word, rack))
"""
In this fourth Scrabble exercise, we will determine the score of a word. You
will define scrabble_score_word(row, k, word) to return the score for playing
word at position k in the row. We extend the notation for rows: a row is still
represented as a list of squares, but now a square can be: (1) a letter, (2)
the start square, represented by the digit 0, (3) an empty square, or empty
double- or triple-letter score square, represented by the integers 1, 2, 3,
respectively, (4) an empty double- or triple-word square, represented by -2 or
-3, respectively. To compute the score, you add up all the points for the
letters first (counting letters double or triple as appropriate), then you
multiply by any double or triple word scores (there might be several of these).
Finally, if all seven letters were used, add a 35 point bonus. The scores for
each letter are as """
D = dict(A=1, B=4, C=4, D=2, E=1, F=4, G=3, H=3, I=1, J=10, K=5, L=2, M=4, N=2,
O=1, P=4, Q=10, R=1, S=1, T=1, U=2, V=5, W=4, X=8, Y=3, Z=10)
def score_test():
assert scrabble_score_word([-3, 1, 1, 2, 1, 1, 'O', 'X', 'I', 'D', 'I', 'Z', 'I', 'N', 'G', -3], 0, 'SESQUIOXIDIZINGS') == 539
assert scrabble_score_word([-3, 1, 2, 1, 'T', 1, 2, 1, -3], 1, 'BROTHERS') == 80
assert scrabble_score_word([-3, 1, 2, 1, '*', 1, 2, 1, -3], 2, 'ZOOLOGY') == 227
assert scrabble_score_word([-3, 1, 2, 'O', '*', 1, 2, 1, -3], 2, 'ZOOLOGY') == 192
assert scrabble_score_word([-3, 1, 2, 1, 'T', 1, 2, 1, -3], 3, 'OTHER') == 8
assert scrabble_score_word([-3, 1, 2, 1, '*', 1, 2, 1, -3], 0, 'OTHER') == 60
print 'pass'
def scrabble_score_word(row, k, word):
row_part = row[k:k+len(word)]
score = sum(D[w]*mult
for w,mult in zip(word, translate(row_part)))
for l in row_part:
if l < 0:
score *= -l
score *= [1, 2]['*' in row_part]
return score + 35 * (len(word) - len([l for l in row_part if l in LETTERS]) == 7)
def translate(row):
return [i if i in (1, 2, 3) else 1 for i in row]
#peter's
def scrabble_score_word(row, k, word):
# W is word multiplier; L is letter multiplier; N is number of letters placed
total, W, N = 0, 1, 0
for (i, ch) in enumerate(word):
sq = row[i+k]
if sq in (-2, -3, '*'): W = W * (2 if sq=='*' else -sq)
if sq not in letters: N = N + 1
L = sq if (sq in (1, 2, 3)) else 1
total = total + L * letterscores[ch]
return W * total + (35 if (N == 7) else 0)
letterscores = dict(A=1, B=4, C=4, D=2, E=1, F=4, G=3, H=3, I=1, J=10, K=5, L=2, M=4, N=2, O=1, P=4, Q=10, R=1, S=1, T=1, U=2, V=5, W=4, X=8, Y=3, Z=10)
letters = set(letterscores)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment