1

How do elegantly rearrange my code so I can get the output {:monosyllabic=>3, :polysyllabic=>4} instead of the other way around?

def polysyllabic(dictionary)

  words = Hash.new(0)
  dictionary.each do |word|
  if word.scan(/[aeiou]/).size > 1
    words[:polysyllabic] += 1
  else
    words[:monosyllabic] +=1
  end
end

polysyllabic(%w(puts locker aero mass ana put pets))

edit: Yes I thought that there are 3 monosyllabics : mass, put, pets. I and some others pronounce "puts" "like "put s" so I want to classify it as polysyllabic. Correct me if I am wrong.

catcher
  • 31
  • 1
  • 3
  • There are 4 monosyllabic: `puts`, `mass`, `put`, `pets`, the code is correct. (execpt that you are missing an `end` and you need `puts words` to see the result) – Yu Hao May 23 '15 at 18:00
  • if the question is about the order you cannot force the order in a hash – Mircea May 23 '15 at 18:09
  • Hashes should be considered unordered, although they are currently ordered by insertion order. Instead retrieve the keys in the order you want, and use them to access their respective values. – Dave Newton May 23 '15 at 18:12
  • I thought the question is why `:monosyllabic` has a value of `4`, not `3`. What is the question exactly? – Yu Hao May 23 '15 at 18:16
  • @Dave, I rarely take issue with you, but I cannot agree that "Hashes should be considered unordered`", as I've encountered numerous situations were the maintenance of insertion order (v. 1.9+) was the key to dealing with a problem in an elegant way. If you've been raised on hashes, I expect it's hard to let go... – Cary Swoveland May 23 '15 at 18:30
  • Maintenance of insertion order is orthogonal to relying on a specific implementation, which could change. – Dave Newton May 23 '15 at 18:48
  • Yes I thought that there are 3 monosyllabics : mass, put, pets. I and some others pronounce "puts" "like "put s" so I want to classify it as polysyllabic. Correct me if I am wrong. – catcher May 23 '15 at 19:04
  • @catcher write down formal rules, how a word should be pronounced. These rules should explain why "puts" has "s" pronounced separately, but not "pets", "pits" and "pots". This is the hard part. Then just code the rules, should be trivial – Sergio Tulentsev May 23 '15 at 20:45
  • For bonus points: once you're done with the rules, what do they say about `strftime`? :) – Sergio Tulentsev May 23 '15 at 20:46
  • If you're trying to write something more general, you've got a couple of problems. First, you probably want `/[aeiouy]/`, and second, you may want to extend that to `/[aeiouy]+/` so you don't count words like 'bean' as polysyllabic. – pjs May 23 '15 at 20:48

2 Answers2

1

Here is a cleaned up version of your code:

def polysyllabic dictionary
  dictionary.each.with_object(Hash.new(0)) do |word, h|
    h[(word.count('aeiou') > 1) ? :polysyllabic : :monosyllabic] += 1
  end
end

Hashes in later versions of Ruby keep the order in which keys were added to the hash.

p polysyllabic(%w(puts locker aero mass ana put pets))
# => {:monosyllabic=>4, :polysyllabic=>3}
p polysyllabic(%w(locker aero mass ana put pets))
# => {:polysyllabic=>3, :monosyllabic=>3}

In the first case, 'puts' is monosyllabic, and that gets defined in the hash first, so the output of the hash reflects that. In the second case, 'locker' is poly, and so that is output first. To ensure sorted output, write a new method for that behavior.

class Hash
  def sorted_keys
    sort.to_h
  end
end

p polysyllabic(%w(locker aero mass ana put pets)).sorted_keys
# => {:monosyllabic=>3, :polysyllabic=>3}

This sorts an array form of the hash, then converts back to a hash.

Brian Davis
  • 357
  • 3
  • 7
-1
def polysyllabic(dictionary)

  words = {:monosyllabic=>0, :polysyllabic=>0}
steenslag
  • 79,051
  • 16
  • 138
  • 171