Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kballenegger/c10f856d3d45647d96b41af798dd3c05 to your computer and use it in GitHub Desktop.
Save kballenegger/c10f856d3d45647d96b41af798dd3c05 to your computer and use it in GitHub Desktop.
Shortest path between strings only substitutions
Words = Set.new
File.open('/usr/share/dict/words') do |file|
file.each do |line|
Words.add(line.strip)
end
end
Alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('')
def path(input, output)
input, output = input.downcase, output.downcase
path_recursive(input, output, [input], Hash.new)
end
def path_recursive(input, output, progress, memory)
return progress if input == output
similar_words = []
return memory[[input, output]] if memory[[input, output]]
(0..(input.length-1)).each do |i|
next if input[i] == output[i]
replacements = Alphabet - [input[i]]
replacements.each do |r|
modified = input.clone; modified[i] = r
next unless Words.include?(modified)
similar_words << modified
end
end
paths = []
(similar_words - progress).each do |word|
if (p = path_recursive(word, output, progress + [word], memory))
paths << p
end
end
paths.sort_by(&:length).first.tap {|r| memory[[input, output]] = r }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment