William James wrote: > Simon Kröçer wrote: > > William James wrote: > > > Short: > > > [ clipped ] > > > > Using Dominik's nice idea i boiled it down to: > > (the dictionary is the optional third parameter, no -d) > > > > ----------------------------------------------------------- > > dict, len = Hash.new{|h,k|h[k] = []}, ARGV[0].size > > IO.foreach(ARGV[2] || 'words.txt') do |w| w.chomp! > > if w.size != len then next else s = w.dup end > > (0...w.size).each{|i|s[i]=?.; dict[s] << w; s[i]=w[i]} > > end > > t, known = {ARGV[1] => 0}, {} > > while !known.merge!(t).include?(ARGV[0]) > > t = t.keys.inject({}){|h, w|(0...w.size).each{|i| > > s=w.dup; s[i]=?.; dict[s].each{|l|h[l] = w if !known[l]}};h} > > warn 'no way!' or exit if t.empty? > > end > > puts w = ARGV[0]; puts w while (w = known[w]) != 0 > > ----------------------------------------------------------- > > > > It's still quite fast. > > Yours is faster and produces shorter chains. I shortened it a > tiny bit. > [ clipped ] Shorter still: dict = Hash.new{|h,k| h[k] = [] } IO.foreach($*[2] || 'words.txt') do |w| w.chomp! next if w.size != $*[0].size w.size.times{|i| dict[w[0,i]+"."+w[i+1..-1]] << w} end t, known = {$*[1], 0}, {} while !known.merge!(t).key?($*[0]) t = t.keys.inject({}){|h, w| (0...w.size).each{|i| s=w.dup s[i]=?.; dict[s].each{|l| h[l] = w if !known[l] }}; h } warn 'no way!' or exit if t=={} end puts w = $*[0]; puts w while (w = known[w]) != 0