Last active
December 24, 2015 06:29
-
-
Save JFickel/6757108 to your computer and use it in GitHub Desktop.
Twitch.tv Spellchecker
This file contains hidden or 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
require_relative "spellchecker" | |
spellchecker = SpellChecker.new | |
while true | |
print '> ' | |
word = gets.chomp | |
puts spellchecker.suggest(word) | |
end |
This file contains hidden or 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
class SpellChecker | |
VOWELS = ['a', 'e', 'i', 'o', 'u'] | |
attr_reader :words | |
def initialize | |
@words = File.readlines('/usr/share/dict/words').map{|word| word.downcase.chomp} | |
index_words | |
end | |
def index_words | |
@words = @words.group_by{|word| word[0]} | |
@words.each do |key, value| | |
@words[key] = value.group_by {|word| word[1] } | |
end | |
@words.each do |key, value| | |
value.each do |key2, value2| | |
@words[key][key2] = value2.group_by {|word| word[2]} | |
end | |
end | |
end | |
def suggest(word) | |
@repeat_variations = [] | |
@total_variations = [] | |
variate_repeated_letters count_letters(word.downcase.strip) | |
@repeat_variations.each do |possibility| | |
variate_vowel possibility | |
end | |
@total_variations.unshift word.downcase.strip | |
find_possible_word | |
end | |
def find_possible_word | |
@total_variations.each do |variation| | |
possibilities = @words[variation[0]] | |
if @words[variation[0]] && @words[variation[0]][variation[1]] | |
possibilities = @words[variation[0]][variation[1]][variation[2]] | |
elsif @words[variation[0]] | |
possibilities = @words[variation[0]][variation[1]] | |
end | |
unless possibilities.nil? | |
possibilities.each do |possibility| | |
if possibility == variation | |
return possibility | |
end | |
end | |
end | |
end | |
return "NO SUGGESTION" | |
end | |
def variate_vowel word, index=0 | |
remaining_word = word[index..-1] | |
remaining_word.each_char.with_index do |char, char_i| | |
if VOWELS.include? char | |
VOWELS.each do |vowel| | |
possibility = word.dup | |
possibility[index+char_i] = vowel | |
forward_string = word[1+char_i+index..-1] | |
if VOWELS.any? {|e| forward_string.include? e} | |
variate_vowel possibility, index+char_i+1 | |
else | |
@total_variations << possibility | |
end | |
end | |
return | |
end | |
end | |
end | |
def count_letters word | |
word.each_char.with_object([]) do |char, obj| | |
last_character = obj.pop | |
if !last_character.nil? && last_character[0] == char | |
last_character[1] += 1 | |
obj.push last_character | |
elsif last_character.nil? | |
obj.push [char, 1] | |
else | |
obj.push last_character | |
obj.push [char, 1] | |
end | |
end | |
end | |
def variate_repeated_letters letter_counter, index=0 | |
unless letter_counter.any? {|lcount| lcount[1] > 1} | |
@repeat_variations << letter_counter.each.with_object("") {|letter_count,obj| letter_count[1].times { obj << letter_count[0]}} | |
return | |
end | |
remaining_letters = letter_counter[index..-1] | |
remaining_letters.each.with_index do |lcount, i| | |
if lcount[1] > 1 | |
lcount[1].times do |num| | |
possibility = lcount.dup | |
possibility[1] = num+1 | |
forward_letters = letter_counter[1+i+index..-1] | |
word = letter_counter.dup | |
word[index+i] = possibility | |
if forward_letters.any? {|lcount| lcount[1] > 1} | |
variate_repeated_letters word, index+i+1 | |
else | |
@repeat_variations << word.each.with_object("") {|letter_count,obj| letter_count[1].times { obj << letter_count[0]}} | |
end | |
end | |
return | |
end | |
end | |
end | |
end |
This file contains hidden or 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
require_relative "spellchecker" | |
describe "spellcheck" do | |
it "should return a word" do | |
expect(SpellChecker.new.suggest("people")).to eq("people") | |
end | |
it "should return a word with a misplaced vowel" do | |
expect(SpellChecker.new.suggest("peeple")).to eq("people") | |
end | |
it "should return a word with repeated letters" do | |
expect(SpellChecker.new.suggest("ppeople")).to eq("people") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment