My last email seemed to disappear in the ether, so here it is again.
Hi, one very simple (and short .. and slow) solution. --will
require 'set'
#read in every word into a hash
def read_dictionary(filename, length)
words = IO.readlines(filename).collect{ |l|
l.strip.downcase }.reject{ |word| word.length != length }
Set.new(words)
end
#computes all possible neighbours of a word
def get_neighbours(word)
allneigbours = Set.new
for i in 0...word.length
for c in 97..122
neighbour = word.dup
neighbour[i] = c
allneigbours.add(neighbour)
end
end
allneigbours
end
#performs the word chain search
def compute(a, b, dict)
raise "words are different lengths" if a.length != b.length
#setup
dictionary = read_dictionary(dict, a.length)
raise b+" not in dictionary" if !dictionary.include?(b)
queue = [ [a] ]
seen = Set.new([a])
#very simple breadth first search
while queue.length > 0
solution = queue.delete_at(0)
break if solution.last == b
#get neighbours
neighbours = get_neighbours(solution.last)
neighbours &= dictionary
neighbours -= seen
seen += neighbours
#add onto queue
neighbours.each_with_index { |obj, i|
queue.push( solution.dup.push(obj) )
}
end
raise "cannot create word chain" if solution.last != b
puts solution
end
#parse options very simply
dict = "/usr/share/dict/words"
a = ARGV.shift
if a == "-d"
dict = ARGV.shift
a = ARGV.shift
end
b = ARGV.shift
#do it
compute(a, b, dict)