Last active
April 27, 2017 15:14
-
-
Save crazymykl/4fafe47d806606b1d2fa887a15bc7498 to your computer and use it in GitHub Desktop.
Find words that sorta rhyme with the input
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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