Hashes "most_common_vowel" exercise

I noticed that the solution given to “most_common_vowel” in the hashes exercises doesn’t actually meet the second requirement (“If there’s a tie, return the vowel that occurs earlier in the alphabet.”)

If you run the specs on the solution, it passes, but that’s because the test for that requirement uses the test string “eeiaoa”, and if there’s a tie the given solution returns the vowel that is added to the counts hash last—“a” in this case—not the vowel that occurs first in the alphabet.

There are a lot of ways to solve this. For reference here’s the given solution:

def most_common_vowel(string)
  vowels = %w(a e i o u)
  counts = Hash.new(0) # Give the hash a default value of 0

  string.each_char do |character|
    counts[character] += 1 if vowels.include?(character)

  counts.sort_by {|k, v| v}.last.first

And here’s the spec:

  describe "most_common_vowel" do
    it "returns the most common vowel" do
      str = "eieeoaa"
      expect(most_common_vowel(str)).to eq("e")

    it "defaults to alphabetical order in case of tie" do
      str = "eeiaoa"
      expect(most_common_vowel(str)).to eq("a")

Here’s my solution:

def most_common_vowel(string)
  sorted_vowels = string.scan(/[aeiou]/).sort.reverse
  tallies = Hash.new(0)
  sorted_vowels.each { |char| tallies[char] += 1 }
  tallies.sort_by { |k, v| v }.last.first

And I would suggest replacing the old test string in the spec with “eeiiaaoouu”.

Nice catch! Thanks for the feedback—we’ll make updates to this exercise soon.