Reputation: 1191
I have a scrabble challenge and have the following list of letters:
letters = ['t', 'u', 'v', 'w', 'x', 'y', 'z']
And following list of words:
word = ['apple', 'whisky', 'yutz', 'xray', 'tux', 'zebra']
Here is the code I'm using to find the words which can be made for a given list of letters:
def valid_word(word, letters):
available_letters = letters[:]
candidate = True
for letter in word:
if letter not in available_letters:
candidate = False
else:
available_letters.remove(letter)
if candidate == True:
return candidate
It gives me output that two words 'yutz' and 'tux' can be made for the current list of letters.
My challenge is what if we replace one of the letter in the list of letters with blank denoted as '_'
in the list. For example 't'
is replaced by '_'
below:
letters = ['_', 'u', 'v', 'w', 'x', 'y', 'z']
How can code still be able to find the same words 'yutz' and 'tux' but replace the missing letter? The expected output is 'yu_z' and '_ux'.
UPDATE:
Here is the code which I tried which does not completely work but kind of give direction to where I am going:
rack_list = []
for letter in letters:
if letter in string.ascii_lowercase:
rack_list.append(letter)
else:
blank_count = user_input.count("_")
def valid_word(word, rack):
available_letters = rack_list[:]
missed_counter = 0
for letter in word:
if letter in available_letters:
available_letters.remove(letter)
else:
missed_counter += 1
if missed_counter <= blank_count:
for i in word:
if i in available_letters:
word += i
else:
word += "_"
return word
Upvotes: 2
Views: 888
Reputation: 4345
There is probably a more efficient solution but this one would work:
letters = ['_', 'u', 'v', 'w', 'x', 'y', 'z']
words = ['apple', 'whisky', 'yutz', 'xray', 'tux', 'zebra']
def valid_word(words, letters):
not_valid = []
valid = []
wild = 0
for letter in letters:
if letter == '_':
wild += 1
for word in words:
missing = 0
for letter in word:
if letter not in letters:
missing += 1
if missing > wild:
not_valid.append(word)
break
if word not in not_valid:
s = ''
for letter in word:
if letter in letters:
s += letter
else:
s += '_'
valid.append(s)
return valid
print(valid_word(words, letters))
#output
['yu_z', '_ux']
So you create a not valid list, a valid list and a wild variable that counts the number of underscores in your letters list.
Then loop through your words. If the number of letters missing from the word is greater than the number of underscores counted by wild, add the word to your not valid list. Otherwise add it letter by letter your valid list, replacing any missing letters with an underscore.
Upvotes: 1
Reputation: 77880
Instead of simply setting candidate
to False
, keep a counter of how many letters have been missed. When that count exceeds the quantity of blanks in the rack, then you disqualify the word.
Also, please note that if candidate == True
is redundant. Use simply if candidate
. The value is already Boolean; there's no need to test it.
Code changes per OP's added attempt:
Your main problem was having the final print inside the loop; until you've checked all letters (finished the loop), you don't know whether the word is possible.
def valid_word(word, rack):
available_letters = rack[:]
blank_count = available_letters.count('_')
# print available_letters, blank_count
missed_counter = 0
for letter in word:
if letter in available_letters:
available_letters.remove(letter)
else:
missed_counter += 1
# print word, missed_counter
if missed_counter <= blank_count:
print(word)
# Test program
rack = ['_', 'u', 'v', 'w', 'x', 'y', 'z']
lexicon = ['apple', 'whisky', 'yutz', 'xray', 'tux', 'xyzzy', 'zebra']
for word in lexicon:
valid_word(word, rack)
Output:
yutz
tux
Upvotes: 4
Reputation: 1455
In [1]: def valid_word(word, rack_list):
...: wrd = [w for w in word]
...: for l in rack_list:
...: try:
...: wrd.remove(l)
...: except:
...: pass
...: return len(wrd) <= ll.count('_')
...:
In [2]: valid_word('tux', ['_', 'u', 'v', 'w', 'x', 'y', 'z'])
Out[2]: True
In [3]: valid_word('apple', ['_', 'u', 'v', 'w', 'x', 'y', 'z'])
Out[3]: False
In [4]: valid_word('apple', ['_', 'u', 'v', 'w', 'x', 'y', 'l', 'z', '_', 'p', '_', 'p', 'e'])
Out[4]: True
should work for you
Upvotes: 1