From: Tom Felker Date: 2003-09-17T10:13:14+09:00 Subject: Re: scrambler one-liner OK, here's the unscrambler code. Be warned, I chose a rather memory intensive algorithm, it takes about 110 MB of memory with my 2.4 MB words file. I don't know how the Perl I gave works, but it only took about 35 MB. Anyway, it's very fast after the 5 seconds or so to load the word list. It works by reading a word list to make a hash, with the keys being the word alphabetically instead of randomly scrambled, and the values being the list of unscrambled words. I was amazed at how many words are unique. #!/usr/bin/env ruby class Unscrambler def initialize(wordsFilename = "/usr/share/dict/words") @wordsHash = Hash.new{ Array.new } File.open(wordsFilename) do |wordsFile| wordsFile.each_line do |word| word.chomp! @wordsHash[Unscrambler::word_to_key(word)] <<= word end end end def Unscrambler::word_to_key(word) return word unless word.size > 3 array = word.split(//) array[1..-2] = array[1..-2].sort return array.join; end def unscramble(word) return @wordsHash[Unscrambler::word_to_key(word)] end end puts "Loading wordlist..." if $stdin.isatty u = Unscrambler.new puts "Ready." if $stdin.isatty $stdin.each_line do |line| line.gsub!(/\w+/) do |match| choices = u.unscramble(match.downcase) case choices.size when 0 then match when 1 then choices[0] else "[" + choices.join(", ") + "]" end end print line end -- Tom Felker, - Stop fiddling with the volume knob. Torvalds, explaining SCO's actions: "They are smoking crack."