-
Notifications
You must be signed in to change notification settings - Fork 540
Phoenix - Elzara T. #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,168 @@ | ||
import random | ||
|
||
# Dictionary of the letters with their quantities | ||
LETTER_POOL = { | ||
"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, | ||
} | ||
|
||
# Dictionary assigning point values to the letters | ||
LETTERS_VALUE = { | ||
"A": 1, | ||
"B": 3, | ||
"C": 3, | ||
"D": 2, | ||
"E": 1, | ||
"F": 4, | ||
"G": 2, | ||
"H": 4, | ||
"I": 1, | ||
"J": 8, | ||
"K": 5, | ||
"L": 1, | ||
"M": 3, | ||
"N": 1, | ||
"O": 1, | ||
"P": 3, | ||
"Q": 10, | ||
"R": 1, | ||
"S": 1, | ||
"T": 1, | ||
"U": 1, | ||
"V": 4, | ||
"W": 4, | ||
"X": 8, | ||
"Y": 4, | ||
"Z": 10, | ||
} | ||
|
||
|
||
def draw_letters(): | ||
pass | ||
|
||
# Draw 10 letters randomly, considering the quantity limits | ||
letter_list = list(LETTER_POOL.keys()) | ||
tiles = {} # Dictionary with letter and count to avoid nested loops | ||
letter_bank = [] | ||
|
||
while len(letter_bank) < 10: | ||
random_number = random.randint(0, len(letter_list) - 1) | ||
random_letter = letter_list[random_number] | ||
|
||
if random_letter in tiles: | ||
if tiles[random_letter] >= LETTER_POOL[random_letter]: | ||
continue | ||
tiles[random_letter] += 1 | ||
else: | ||
tiles[random_letter] = 1 | ||
|
||
letter_bank.append(random_letter) | ||
|
||
return letter_bank | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overall, this function looks good! It's a different approach than most that I've seen so far and it's quite clever! The one thing to point out is that while you are taking into account quantity limits, your code currently treats every letter as if they have the same chance of being picked! In reality though, there are more "A"s than "Q"s so the probability of picking an A would be much higher and your current algorithm doesn't take that into account! I will say this wasn't required and it wasn't a test case, so you are not required to include that, but if you have some extra time and would like to try an implementation that weights the letters, feel free to do so! |
||
|
||
|
||
# Count occurrences of a letter in an iterable | ||
def count_items(item, iterable): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love the way you built your own count method here! It is a builtin method, but being able to write it yourself can help you better understand how to use it! Helper functions always encouraged! |
||
count = 0 | ||
for x in iterable: | ||
if x == item: | ||
count += 1 | ||
return count | ||
|
||
|
||
def uses_available_letters(word, letter_bank): | ||
pass | ||
capital_word = word.upper() | ||
|
||
for letter in set(capital_word): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice move to loop through a set as opposed to the entire capital word! Good catch to avoid duplicates! |
||
if letter not in letter_bank or count_items(letter, capital_word) > count_items( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great use of your helper functions! |
||
letter, letter_bank | ||
): | ||
return False | ||
return True | ||
|
||
|
||
def score_word(word): | ||
pass | ||
# Calculate score | ||
score = 0 | ||
for letter in word.upper(): | ||
score += LETTERS_VALUE[letter] | ||
|
||
# Add bonus points for words of length 7-10 | ||
if len(word) >= 7 and len(word) <= 10: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks good! Remember that we have a slightly more concise way to write a conditional to figure out if a value falls into some range. What might that look like? |
||
score += 8 | ||
return score | ||
|
||
|
||
# Function to find the maximum value in a list of numbers | ||
def calculate_max(iterable): | ||
max = 0 | ||
for value in iterable: | ||
if value > max: | ||
max = value | ||
return max | ||
|
||
|
||
# Function to find the minimum length of words in a list | ||
def calculate_min_length(list_of_words): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Love these helpers! |
||
if not list_of_words: | ||
return None | ||
|
||
min_length = len(list_of_words[0]) | ||
for word in list_of_words: | ||
if len(word) < min_length: | ||
min_length = len(word) | ||
return min_length | ||
|
||
|
||
def get_highest_word_score(word_list): | ||
pass | ||
# Calculate scores of each word | ||
word_score = {} | ||
for word in word_list: | ||
score = score_word(word) | ||
word_score[word] = score | ||
|
||
# Calculate max score | ||
max_score = calculate_max(word_score.values()) | ||
|
||
# Find all candidate words with max scores | ||
candidates = [] | ||
for word, score in word_score.items(): | ||
if score == max_score: | ||
candidates.append(word) | ||
|
||
# Find minimum length in candidates | ||
min_length = calculate_min_length(candidates) | ||
|
||
# Determine a winner considering rules | ||
current_winner = "" | ||
for word in candidates: | ||
if len(word) == 10: | ||
current_winner = word | ||
break | ||
if len(word) == min_length and not current_winner: | ||
current_winner = word | ||
|
||
return current_winner, max_score | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overall this function works and passes all the tests, so great job! Specifically, this is a really great way to separate out each section of data and then parse through it one at a time. There is nothing inherently wrong with that and it's a great way to learn and make sure you understand each step that you are doing! Once challenge I have for you is to remember that when it comes to these sorts of algorithms, it can be super helpful to keep in mind what information you need to store as well as what information you don't! For example, we really only need to hold onto words that could be or are the highest scoring word. We don't really care about any of the other words! The dictionary you create maps every word to a score but we likely won't need most of those scores and the words that map to them. Your logic is super sound for how to discover which word and score to update and I think you could leverage that logic to limit the number of extra dictionaries and lists that you create here! No need to make the actual change, but it is something to think about moving forward! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both of these global dictionaries look great!