I am trying to make a program which will find the optimal word to eliminate the most letters from the keyboards alphabet at once when given a list of words. My program always returns "0". I would expect the value to be around 5. I suspect my error is in the "get_best_word" function, but it could be the "get_possible_letters" function as well. I would appreciate any help, my code is as follows.
import os
import random
wordlist = ['crane', 'soare', 'adieu', 'wario', 'crazy', 'aback', 'Abuse','Adult', 'Agent', 'Anger', 'Apple', 'Award', 'Basis', 'Beach', 'Birth', 'Block', 'Blood', 'Board', 'Brain', 'Bread', 'Break', 'Brown', 'Buyer', 'Cause', 'Chain', 'Chair', 'Chest', 'Chief', 'Child', 'China', 'Claim', 'Class', 'Clock', 'Coach', 'Coast', 'Court', 'Cover', 'Cream', 'Crime', 'Cross', 'Crowd', 'Crown', 'Cycle', 'Dance', 'Death', 'Depth', 'Doubt', 'Draft', 'Drama', 'Dream', 'Dress', 'Drink', 'Drive', 'Earth', 'Enemy', 'Entry', 'Error', 'Event', 'Faith', 'Fault', 'Field', 'Fight', 'Floor', 'Focus', 'Force', 'Frame', 'Frank', 'Front', 'Fruit', 'Glass', 'Grant', 'Grass', 'Green', 'Group', 'Guide', 'Heart', 'Henry', 'Horse', 'Hotel', 'House', 'Image', 'Index', 'Input', 'Issue', 'Japan', 'Jones', 'Judge', 'Knife', 'Laura', 'Layer', 'Level', 'Lewis', 'Light', 'Limit', 'Lunch', 'Major', 'March', 'Match', 'Metal', 'Model', 'Money', 'Month', 'Motor', 'Mouth', 'Music', 'Night', 'Noise', 'North', 'Novel', 'Nurse', 'Offer', 'Order', 'Other', 'Owner', 'Panel', 'Paper', 'Party', 'Peace', 'Peter', 'Phase', 'Phone', 'Piece', 'Pilot', 'Pitch', 'Place', 'Plane', 'Plant', 'Plate', 'Point', 'Pound', 'Power', 'Press', 'Price', 'Pride', 'prize', 'Proof', 'Queen', 'Radio', 'Range', 'Ratio', 'Reply', 'Right', 'River', 'Round', 'Route', 'Rugby', 'Scale', 'Scene', 'Scope', 'Score', 'Sense', 'Shape', 'Share', 'Sheep', 'Sheet', 'Shift', 'Shirt', 'Shock', 'Sight', 'Simon', 'Skill', 'Sleep', 'Smile', 'Smith', 'Smoke', 'Sound', 'South', 'Space', 'Speed', 'Spite', 'Sport', 'Squad', 'Staff', 'Stage', 'Start', 'State', 'Steam', 'Steel', 'Stock', 'Stone', 'Store', 'Study', 'Stuff', 'Style', 'Sugar', 'Table', 'Taste', 'Terry', 'Theme', 'Thing', 'Title', 'Total', 'Touch', 'Tower', 'Track', 'Trade', 'Train', 'Trend', 'Trial', 'Trust', 'Truth', 'Uncle', 'Unity', 'Value', 'Video', 'Visit', 'Voice', 'Waste', 'Watch', 'Water', 'While', 'White', 'Whole', 'Woman', 'World', 'Youth']
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
def get_possible_letters(word):
possible_letters = letters
for i in word:
if i in possible_letters:
possible_letters.remove(i)
return possible_letters
class Word:
def __init__(self, text, coloured_text):
self.text = text
self.coloured_text = coloured_text
def get_best_word():
max_score = len(letters)
for i in wordlist:
score = len(get_possible_letters(i))
if score < max_score:
max_score = score
return score
print(get_best_word())
CodePudding user response:
You should be counting the letters by an int
counter
. Rather than taking the length of a list
:
def get_possible_letters(word):
possible_letters = letters.copy()
counter = 0
for i in word:
if i in possible_letters:
possible_letters.remove(i)
counter = 1
return counter
Then you need to make a current_score
, rather than a maximum score. And only update it when you find one better score > current_score
.
def get_best_word():
current_score = 0
for i in wordlist:
score = get_possible_letters(i)
if score > current_score:
current_score = score
return current_score
This will try and get the lowest scoring word (4
)
if score < max_score:
max_score = score
CodePudding user response:
possible_letters = letters[:]
Create a copy of letters
using slicing. Otherwise you change the original list - which is not what you want since you need to check against it everytime. Here is the correct code and possible solution:
import os
import random
wordlist = ['crane', 'soare', 'adieu', 'wario', 'crazy', 'aback', 'Abuse','Adult', 'Agent', 'Anger', 'Apple', 'Award', 'Basis', 'Beach', 'Birth', 'Block', 'Blood', 'Board', 'Brain', 'Bread', 'Break', 'Brown', 'Buyer', 'Cause', 'Chain', 'Chair', 'Chest', 'Chief', 'Child', 'China', 'Claim', 'Class', 'Clock', 'Coach', 'Coast', 'Court', 'Cover', 'Cream', 'Crime', 'Cross', 'Crowd', 'Crown', 'Cycle', 'Dance', 'Death', 'Depth', 'Doubt', 'Draft', 'Drama', 'Dream', 'Dress', 'Drink', 'Drive', 'Earth', 'Enemy', 'Entry', 'Error', 'Event', 'Faith', 'Fault', 'Field', 'Fight', 'Floor', 'Focus', 'Force', 'Frame', 'Frank', 'Front', 'Fruit', 'Glass', 'Grant', 'Grass', 'Green', 'Group', 'Guide', 'Heart', 'Henry', 'Horse', 'Hotel', 'House', 'Image', 'Index', 'Input', 'Issue', 'Japan', 'Jones', 'Judge', 'Knife', 'Laura', 'Layer', 'Level', 'Lewis', 'Light', 'Limit', 'Lunch', 'Major', 'March', 'Match', 'Metal', 'Model', 'Money', 'Month', 'Motor', 'Mouth', 'Music', 'Night', 'Noise', 'North', 'Novel', 'Nurse', 'Offer', 'Order', 'Other', 'Owner', 'Panel', 'Paper', 'Party', 'Peace', 'Peter', 'Phase', 'Phone', 'Piece', 'Pilot', 'Pitch', 'Place', 'Plane', 'Plant', 'Plate', 'Point', 'Pound', 'Power', 'Press', 'Price', 'Pride', 'prize', 'Proof', 'Queen', 'Radio', 'Range', 'Ratio', 'Reply', 'Right', 'River', 'Round', 'Route', 'Rugby', 'Scale', 'Scene', 'Scope', 'Score', 'Sense', 'Shape', 'Share', 'Sheep', 'Sheet', 'Shift', 'Shirt', 'Shock', 'Sight', 'Simon', 'Skill', 'Sleep', 'Smile', 'Smith', 'Smoke', 'Sound', 'South', 'Space', 'Speed', 'Spite', 'Sport', 'Squad', 'Staff', 'Stage', 'Start', 'State', 'Steam', 'Steel', 'Stock', 'Stone', 'Store', 'Study', 'Stuff', 'Style', 'Sugar', 'Table', 'Taste', 'Terry', 'Theme', 'Thing', 'Title', 'Total', 'Touch', 'Tower', 'Track', 'Trade', 'Train', 'Trend', 'Trial', 'Trust', 'Truth', 'Uncle', 'Unity', 'Value', 'Video', 'Visit', 'Voice', 'Waste', 'Watch', 'Water', 'While', 'White', 'Whole', 'Woman', 'World', 'Youth']
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
def get_possible_letters(word):
possible_letters = letters[:]
word = word.lower()
for c in word:
if c in possible_letters:
possible_letters.remove(c)
return possible_letters
class Word:
def __init__(self, text, coloured_text):
self.text = text
self.coloured_text = coloured_text
def get_best_word():
min_score = len(letters)
for w in wordlist:
score = len(get_possible_letters(w))
if score < min_score:
min_score = score
return len(letters)-min_score
print(get_best_word())
Corrections:
You have to copy the list properly otherwise it still points to the
letters
and it modifies it.You need to use lowercase letters in words since you
letters
list contains only lower case letters.Ideally you are looking for words that has as many different letters as possible but your code for scoring was wrong. You should subtract from total number of letters to get the desired correct number of distinct letter in your words.
Another solution (short)
def get_best_word1():
max_distinct_letters = 0
for w in wordlist:
w = w.lower()
distinct_letters= len(set(list(w)))
if distinct_letters > max_distinct_chars :
max_distinct_chars = distinct_letters
return max_distinct_chars
Few other points: try to use proper variable names. In the last code, you can see that the variables clearly conveys the idea to some extent. This is actually quite helpful for reading the code and understanding it.