Skip to content

Instantly share code, notes, and snippets.

@crazymykl
Last active April 27, 2017 15:14
Show Gist options
  • Save crazymykl/4fafe47d806606b1d2fa887a15bc7498 to your computer and use it in GitHub Desktop.
Save crazymykl/4fafe47d806606b1d2fa887a15bc7498 to your computer and use it in GitHub Desktop.
Find words that sorta rhyme with the input
#! /usr/bin/env ruby
def words
@_words ||= open 'cmudict.dict' do |f|
f.each_line.with_object({}) do |line, acc|
word, *phonemes = line.strip.split ' '
acc[word] = phonemes
end
end
rescue Errno::ENOENT
download_dict and retry
end
def download_dict
require 'open-uri'
download = open 'https://raw.githubusercontent.com/cmusphinx/cmudict/master/cmudict.dict'
IO.copy_stream download, 'cmudict.dict'
end
def vowel_key phonemes
phonemes.select { |ph| ph[0] =~ /[AEIOU]/ }
end
def rhymes
@_rhymes ||= Hash.new { |h, k| h[k] = [] }.tap do |h|
words.each do |k, v| h[vowel_key(v)] << k end
end
end
def common? word
%w[that this with from your have will you're i've].include? word
end
def simple? word
word.length < 4 || common?(word) || !words.key?(word)
end
def rhyme_for word
return word if simple?(lword = word.downcase)
rhyme = rhymes[vowel_key(words[lword])]
.sample
.sub %r[\(\d+\)\z], ''
word.capitalize == word ? rhyme.capitalize : rhyme
end
def rhyme_each_word line
line.strip.gsub(/[\w']+/) { |w| rhyme_for w }
end
if __FILE__ == $0
puts rhyme_each_word gets until STDIN.eof?
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment