Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > [SUMMARY] Rhyming Words (#195)

Reply
Thread Tools

[SUMMARY] Rhyming Words (#195)

 
 
Daniel Moore
Guest
Posts: n/a
 
      03-15-2009
This week's quiz had an excellent solution from Eugene Kalenkovich.

In order to get this to work on my machine in 1.8 or 1.9 I had to add
the following:

# Adding 1.9 and 1.8 compatibility
if :a.respond_to? :to_proc
class String
include Enumerable
alias :each :each_line
end
else
class Symbol
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
end
end

This is probably not the best overall solution to make code 1.9
compatible, but it does illustrate some of the differences between
Ruby versions. It appears as though the code was written for 1.8 but
with Facets or another library defining `Symbol#to_proc`.

Eugene's solution requires a database (plain text file of words and
pronunciations) to operate. The file contains entries in the following
form:

# ...
MONGOLS M AA1 NG G AH0 L Z
MONGOOSE M AA1 NG G UW0 S
# ...
REPARATIONS R EH2 P ER0 EY1 SH AH0 N Z
REPARTEE R EH2 P ER0 T IY1
# ...

These are phonetic representations of the words. The readme file that
accompanies the database describes the pronunciations in detail if you
are interested in learning more.

# lookup tables to store the words and rhyming words
$words = Hash.new{|h,k| h[k]=[]}
$rhymes = Hash.new{|h,k| h[k]=[]}

The `perfect_key` method is what determines what words perfectly rhyme
with one another. It iterates through the reverse of the sound list
and stops after adding the first stress. So if the word is 'mongoose'
`perfect_key` will return `["S", "UW0", "G", "NG", "AA1"]`.

# Returns an array of sounds starting at the end and
# going through the first stress
def perfect_key(pron)
key = []
pron.reverse.each do |snd|
key << snd
break if snd =~ /1$/
end
key
end

The rhymes method is used to display the rhyming words in the output.
It gets all the rhyming words for the given word's perfect key and
returns the list minus the word itself.

def rhymes(word)
wup = word.upcase
$rhymes[perfect_key($words[wup])] - [wup]
end

Reading the data file and creating the tables of pronunciation and
words is the bulk of the processing. This section iterates through
each line in the word data file and creates a mapping from the word to
the pronunciation, skipping comment lines or lines that have words
with non-alpha characters. After mapping the word to the pronunciation
it adds the word to the list of rhymes that is mapped by the perfect
key of the pronunciation in the `$rhymes` hash.

File.open('mpron/cmudict0.3') {|f| f.readlines}.each do |l|
w, *pron = l.strip.split(' ')
next unless !w.empty? and w.grep(/[^A-Z]/).empty?
pron.map!{|sound| sound.sub(/2/,'1')}
$words[w] = pron
$rhymes[perfect_key(pron)] << w
end

The program will find rhymes for all command line arguments passed in,
or some example arguments if none are given. Having already loaded the
data into a mapping that is convenient, all that is left is to lookup
the lists of words that match the given words perfect rhymes and print
them out.

input = ARGV.empty? ? ['laughter', 'soaring', 'antelope'] : ARGV
results = input.map do |w|
w + ': ' + rhymes(w).map(&:downcase).join(', ') + "\n"
end.join("\n")

print results

Thank you, Eugene, for a very cool solution!

http://rubyquiz.strd6.com/quizzes/195

- Daniel

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Replace stop words (remove words from a string) BerlinBrown Python 6 01-17-2008 02:37 PM
java rhyming dictionary/Thesaurus for phones? Ciaran Java 0 04-19-2007 02:17 AM
Words Words utab C++ 6 02-16-2006 07:00 PM
Non-noise words are incorrectly recognised as noise words. Peter Strĝiman ASP .Net 1 08-23-2005 01:26 PM
Re: A little bit of help regarding my linked list program required. - "words.c" - "words.c" Richard Heathfield C Programming 7 10-05-2003 02:38 PM



Advertisments