Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions lib/adagrams.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
require "pry"

def draw_letters
alphabet_soup = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making this hash a global variable using all caps that is defined outside the method.

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,
}
hand = []
10.times do |letter, quantity|
letter_selection = alphabet_soup.keys.sample

while alphabet_soup[letter_selection] == 0
letter_selection = alphabet_soup.keys.sample
end
alphabet_soup[letter_selection] -= 1

hand << letter_selection.to_s
end
return hand
end

def uses_available_letters?(input, letters_in_hand)
dup_array = letters_in_hand.dup

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you are returning the value returned from a block of code, explicitly assign that value to a variable, and then return that variable.

input.upcase.split(//).all? do |letter|
  included = dup_array.include?(letter)
  dup_array.delete(letter)
end
return included

return input.upcase.split(//).all? do |letter|
included = dup_array.include?(letter)
dup_array.delete(letter)
included
end
end

def score_word(word)
score = 0

word_array = word.upcase.split(//)
word_array.each do |letter|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this case statement works, it means that the information about which letter has which score is locked into this piece of code, and can't easily be used elsewhere. For example, if you wanted to display the value of each letter in a hand, you would need to repeat this work.

An alternative approach would be to store the letter scores in a hash, something like this:

LETTER_SCORES = {
  "A" => 1
  "B" => 3,
  "C" => 3,
  "D" => 2,
  # ...
}

Then to get the score for a letter, you can say LETTER_SCORES[letter].

case letter

when "A", "E", "I", "O", "U", "L", "N", "R", "S", "T"
score += 1
when "D", "G"
score += 2
when "B", "C", "M", "P"
score += 3
when "F", "H", "V", "W", "Y"
score += 4
when "K"
score += 5
when "J", "X"
score += 8
when "Q", "Z"
score += 10
end
end

if word.length > 6 && word.length < 11
score += 8
end
return score
end

def highest_score_from(words)
winning_words = {
word: "",
score: 0,
}
new_hash = {}
score_array = words.map { |string| score_word(string) }
words.zip(score_array) { |word, score| new_hash[word] = score.to_i }

max_score = new_hash.values.max

winners = new_hash.select { |word, score| score == max_score }
winners_array = winners.keys

winners_array.each do |word|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here is a bit complicated and you still have not passed that one test:

  test_0006_in case of tied score, prefers most the word with 10 letters regardless of order FAIL (0.00s)
        Expected: "AAAAAAAAAA"
          Actual: "BBBBBB"

It seems that if instead of nesting if/else control structures a chained conditional would simplify your logic. Here is such a chained conditional for a tiebreaker between 2 words.

def tiebreaker(word1, word2)
    if word1.length == 10
      return word1
    elsif word2.length == 10
      return word2
    elsif word1.length < word2.length
      return word1
    elsif word1.length > word2.length
      return word2
    else
      word1
    end
  end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using comments to outline the logic of the tiebreakers rules

if winners_array.length == 1
winning_words[:word] = word
winning_words[:score] = winners[word]

return winning_words
else
if word.length == 10
winning_words[:word] = word
winning_words[:score] = winners[word]
return winning_words
elsif words.index(winners_array.first) > words.index(winners_array.last)
winning_words[:word] = winners_array.last
winning_words[:score] = winners[winners_array.last]
return winning_words
end

if word.length < 10
min_word = winners.keys.min_by do |each_word|
each_word.length
end
winning_words[:word] = min_word
winning_words[:score] = winners[min_word]
return winning_words
end
end
end
end