From: Yossef Mendelssohn Date: 2007-07-12T03:34:58+09:00 Subject: Re: Hangman (#130) Maybe people aren't trying this quiz because they're busy. I hope it's not because they find it uninteresting. I banged out something fairly quickly during the weekend and was waiting to find some time to clean it up. It seems I won't get that, so I'm going to post what I have now. It's a fairly simple algorithm that uses a combination of the "established" frequency order of letters in the English language, as seen on Linotype machines, and a dictionary (/usr/dict/share/words, of course) to provide the next guess. What I find interesting about this is how many common words it cannot get before exhausting its allotment of wrong guesses. For instance, it won't get "book". Sometimes I'm surprised with the guesses it gives. Maybe the dictionary I'm using is *too* large. ------------------------------------------------------------------------------- #!/usr/bin/env ruby ALLOWED_WRONG_GUESSES = 6 WORD_LIST_FILENAME = '/usr/share/dict/words' WORD_LIST = {} File.open(WORD_LIST_FILENAME) do |f| f.each { |word| WORD_LIST[word.strip.downcase] = true } end FREQUENCY_ORDER = %w{etaoin shrdlu cmfwyp vbgkqj xz}.collect { |elem| elem.split('') }.flatten GUESSES_MADE = {} puts 'Enter a word pattern' old_pattern = pattern = gets.chomp loop do if pattern.match(/^[a-zA-Z\-]+$/) if pattern.match(/-/) if GUESSES_MADE.values.select { |val| val == false }.length > ALLOWED_WRONG_GUESSES puts 'crap I lost' exit end regex = Regexp.new("^#{pattern.downcase.gsub(/-/, '.')}$") possible_words = WORD_LIST.keys.select { |word| word.match(regex) } possible_letters = possible_words.collect { |word| word.split('') }.flatten.uniq guess = ((FREQUENCY_ORDER - GUESSES_MADE.keys) & possible_letters).first puts guess.upcase pattern = gets.chomp GUESSES_MADE[guess] = (pattern != old_pattern) puts "wrong guesses made: #{GUESSES_MADE.values.select { |val| val == false }.length}" old_pattern = pattern else puts 'Yay I won' exit end else puts 'This pattern makes no sense.' exit end end ------------------------------------------------------------------------------- -yossef