diff --git a/lib/adagrams.rb b/lib/adagrams.rb index e69de29..8b96471 100644 --- a/lib/adagrams.rb +++ b/lib/adagrams.rb @@ -0,0 +1,80 @@ +require 'pry' + + +def draw_letters + letters_in_hand = ARRAY_OF_LETTERS.shuffle.slice(1..10) + return letters_in_hand +end + +ARRAY_OF_LETTERS = ["A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "C", "C", "D", "D", "D", "D", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "F", "F", "G", "G", "G", "H", "H", "I", "I", "I", "I", "I", "I", "I", "I", "I", "J", "K", "L", "L", "L", "L", "M", "M", "N", "N", "N", "N", "N", "N", "O", "O", "O", "O", "O", "O", "O", "O", "P", "P", "Q", "R", "R", "R", "R", "R", "R", "S", "S", "S", "S", "T", "T", "T", "T", "T", "T", "U", "U", "U", "U", "V", "V", "W", "W", "X", "Y", "Y", "Z"] + +def uses_available_letters? (input, letters_in_hand) + input = input.upcase.chars + dup_letters_in_hand = letters_in_hand.clone + + + input.each do |chars| + if dup_letters_in_hand.include?(chars) + dup_letters_in_hand.delete(chars) + else + return false + end + end + + check = 0 + input.each do |chars| + if letters_in_hand.include?(chars) + check = 0 + else + check += 1 + end + end + return check == 0 +end + +def score_word(word) + letter_points = { + "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 + } + word_array = word.upcase.chars + word_points = word_array.map do |k, v| + letter_points[k] + end + total_points = word_points.sum + if word.length > 6 && word.length < 11 + total_points += 8 + end + return total_points +end + +def highest_score_from(words) + highest_score_hash = {} + score = 0 + winning_word = "" + + words.each do |object| + word_score = score_word(object) + if word_score > score + score = word_score + winning_word = object + elsif word_score == score + length_of_obj = object.length + length_of_winning_word = winning_word.length + if length_of_winning_word == 10 + winning_word = winning_word + elsif length_of_obj == 10 + winning_word = object + else + winning_word = tiebreaker_length(winning_word, object) + end + end + highest_score_hash[:word] = winning_word + highest_score_hash[:score] = score + end + return highest_score_hash +end + +def tiebreaker_length (old_word, new_word) + tiebreaker_len_arr = [old_word, new_word] + tiebreaker_len_arr.min { |old_word, new_word| old_word.length <=> new_word.length } +end \ No newline at end of file diff --git a/test/adagrams_test.rb b/test/adagrams_test.rb index 90ec44d..4d1348a 100644 --- a/test/adagrams_test.rb +++ b/test/adagrams_test.rb @@ -13,11 +13,11 @@ drawn_letters = draw_letters expect(drawn_letters.size).must_equal 10 end - + it 'returns an array, and each item is a single-letter string' do drawn_letters = draw_letters expect(drawn_letters.size).must_equal 10 - + expect(drawn_letters).must_be_instance_of Array drawn_letters.each do |letter| expect(letter).must_be_instance_of String @@ -25,155 +25,155 @@ end end end - + describe 'uses_available_letters? method' do - + it 'returns true if the submitted letters are valid against the drawn letters' do drawn_letters = ['D', 'O', 'G', 'X', 'X', 'X', 'X', 'X', 'X', 'X'] test_word = 'DOG' - + is_valid = uses_available_letters? test_word, drawn_letters - + expect(is_valid).must_equal true end - + it 'returns false word contains letters not in the drawn letters' do drawn_letters = ['D', 'O', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'] test_word = 'DOG' - + is_valid = uses_available_letters? test_word, drawn_letters - + expect(is_valid).must_equal false end - + it 'returns false word contains repeated letters more than in the drawn letters' do drawn_letters = ['A', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'] test_word = 'AAA' - + is_valid = uses_available_letters? test_word, drawn_letters - + expect(is_valid).must_equal false end - + it 'does not change the letters in hand' do drawn_letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'] dl_copy = drawn_letters.dup - + # Hint: if your implementation of uses_available_letters? # needs to change the hand, you should make a copy first uses_available_letters? 'ABCD', drawn_letters - + expect(drawn_letters).must_equal dl_copy end end - + describe 'score_word method' do it 'returns an accurate numerical score according to the score chart' do expect(score_word("A")).must_equal 1 expect(score_word("DOG")).must_equal 5 expect(score_word("WHIMSY")).must_equal 17 end - + it 'returns a score regardless of input case' do expect(score_word("a")).must_equal 1 expect(score_word("dog")).must_equal 5 expect(score_word("wHiMsY")).must_equal 17 end - + it 'returns a score of 0 if given an empty input' do expect(score_word("")).must_equal 0 end - + it 'adds an extra 8 points if the word is 7 or more characters long' do expect(score_word("XXXXXXX")).must_equal 64 expect(score_word("XXXXXXXX")).must_equal 72 expect(score_word("XXXXXXXXX")).must_equal 80 end end - + describe 'highest_score_from method' do it 'returns a hash that contains the word and score of best word in an array' do words = ['X', 'XX', 'XXX', 'XXXX'] best_word = highest_score_from words - + expect(best_word[:word]).must_equal 'XXXX' expect(best_word[:score]).must_equal 32 end - + it 'accurately finds best scoring word even if not sorted' do words = ['XXX', 'XXXX', 'XX', 'X'] best_word = highest_score_from words - + expect(best_word[:word]).must_equal 'XXXX' expect(best_word[:score]).must_equal 32 end - + it 'in case of tied score, prefers the word with fewer letters' do # the character 'M' is worth 3 points, 'W' is 4 points words = ['MMMM', 'WWW'] - + # verify both have a score of 12 expect(score_word(words.first)).must_equal 12 expect(score_word(words.last)).must_equal 12 - + best_word = highest_score_from words - + expect(best_word[:word]).must_equal 'WWW' expect(best_word[:score]).must_equal 12 end - + it 'in case of tied score, prefers the word with fewer letters regardless of order' do # the character 'M' is worth 3 points, 'W' is 4 points words = ['WWW', 'MMMM'] - + # verify both have a score of 12 expect(score_word(words.first)).must_equal 12 expect(score_word(words.last)).must_equal 12 - + best_word = highest_score_from words - + expect(best_word[:word]).must_equal 'WWW' expect(best_word[:score]).must_equal 12 end - + it 'in case of tied score, prefers most the word with 10 letters' do # the character 'A' is worth 1 point, 'B' is 3 points words = ['AAAAAAAAAA', 'BBBBBB'] - + # verify both have a score of 10 expect(score_word(words.first)).must_equal 18 expect(score_word(words.last)).must_equal 18 - + best_word = highest_score_from words - + expect(best_word[:word]).must_equal 'AAAAAAAAAA' expect(best_word[:score]).must_equal 18 end - + it 'in case of tied score, prefers most the word with 10 letters regardless of order' do # the character 'A' is worth 1 point, 'B' is 3 points words = ['BBBBBB', 'AAAAAAAAAA'] - + # verify both have a score of 10 expect(score_word(words.first)).must_equal 18 expect(score_word(words.last)).must_equal 18 - + best_word = highest_score_from words - + expect(best_word[:word]).must_equal 'AAAAAAAAAA' expect(best_word[:score]).must_equal 18 end - + it 'in case of tied score and same length words, prefers the first word' do # the character 'A' is worth 1 point, 'E' is 1 point words = ['AAAAAAAAAA', 'EEEEEEEEEE'] - + # verify both have a score of 10 expect(score_word(words.first)).must_equal 18 expect(score_word(words.last)).must_equal 18 - + best_word = highest_score_from words - + expect(best_word[:word]).must_equal words.first expect(best_word[:score]).must_equal 18 end