On 4/20/07, Ruby Quiz <james / grayproductions.net> wrote:
> This week's quiz is to write program that displays all possible translations for
> ambiguous words provided in code.
>
> Your program will be passed a word of Morse code on STDIN.  Your program should
> print all possible translations of the code to STDOUT, one translation per line.
> Your code should print gibberish translations in case they have some meaning for
> the reader, but indicating which translations are in the dictionary could be a
> nice added feature.

Here's my  solution. It takes one or more code words from ARGV, and
takes an optional -d argument to use a dictionary file to filter
results.

# RubyQuiz 121 submission
# Bob Showalter

# set to dictionary file to load
DICT = '/usr/share/dict/words'

class Morse

  @@words = nil

  LETTER = Hash[*%w/
     A .-            N -.
     B -...          O ---
     C -.-.          P .--.
     D -..           Q --.-
     E .             R .-.
     F ..-.          S ...
     G --.           T -
     H ....          U ..-
     I ..            V ...-
     J .---          W .--
     K -.-           X -..-
     L .-..          Y -.--
     M --            Z --..
  /]

  # loads dictionary file to limit the words output
  def self.load_dictionary(path)
    @@words = {}
    File.open(path, 'r') do |f|
      while word = f.gets
        @@words[word.chomp.upcase] = true
      end
    end
  end

  # returns list of words starting with prefix that can be made from code
  def self.words(code = @code, prefix = '')
    results = []
    if code == ''
      results << prefix if @@words.nil? || @@words.include?(prefix)
    else
      LETTER.sort.each do |l, p|
        if code[0, p.length] == p
          results += words(code[p.length,code.length], prefix + l)
        end
      end
    end
    results
  end

end

Morse.load_dictionary(DICT) if ARGV.delete('-d')
abort "Usage: #{$0} [-d] code [...]" if ARGV.empty?
ARGV.each do |code|
  puts "#{code}:"
  puts Morse.words(code)
end