Hey!  I'm internet famous! For some reason, I was sure there was a
backlog of suggestions and mine wouldn't come up for a while, if at
all.  Imagine my surprise when it was the very next quiz.

The reason I suggested this is because I wrote it myself about a year
ago (albeit in Perl, my main quick language at the time) in order to
help with a puzzle in Games magazine.  I then promptly forgot about
its existence until recently, when I was reading up on the Ruby Quiz.
It wasn't hard to figure out what to do next.

My own solution follows, ported from my original Perl.  The algorithm
hasn't been changed, mostly just converted.  It's not very quick or
efficient (or elegant), but it works.  Basically I create a trie
(using nested hashes) of the possibilities and then flatten it down to
a single level.

-----

class String

  class << self
    def morse_code_hash=(new_val)
      @@morse_code_hash = new_val
    end

    def morse_code_hash
      @@morse_code_hash
    end
  end

  def morsecode_possibilities
    raise "#{self} is not valid morse code" if self.match(/[^\-\.]/)

    @tree = get_tree

    @possibilities = @tree.flatten.keys.sort
  end

  def get_tree
    starts = @@morse_code_hash.keys.select { |k|  self.match(/
^#{Regexp.escape(k)}/) }

    tree = {}

    starts.each do |start|
      tree[ @@morse_code_hash[start] ] = self[start.length ..
-1].get_tree
    end

    tree
  end

end

class Hash
  def flatten
    tmp = {}
    each do |key, val|
      tmp[key] = val
      if val.is_a?(Hash)
        val.keys.each do |subkey|
          tmp["#{key}#{subkey}"] = val[subkey]
        end
        tmp.delete(key) unless val.empty?
      end
    end
    tmp = tmp.flatten while tmp.values.any? { |v|  !v.empty? }
    tmp
  end
end

codehash = {
  'A' => '.-',
  'B' => '-...',
  'C' => '-.-.',
  'D' => '-..',
  'E' => '.',
  'F' => '..-.',
  'G' => '--.',
  'H' => '....',
  'I' => '..',
  'J' => '.---',
  'K' => '-.-',
  'L' => '.-..',
  'M' => '--',
  'N' => '-.',
  'O' => '---',
  'P' => '.--.',
  'Q' => '--.-',
  'R' => '.-.',
  'S' => '...',
  'T' => '-',
  'U' => '..-',
  'V' => '...-',
  'W' => '.--',
  'X' => '-..-',
  'Y' => '-.--',
  'Z' => '--..'
}


String.morse_code_hash = codehash.invert

code = (ARGV.first || '').chomp

exit if code.empty?

puts "Getting possibilities for '#{code}':"

puts code.morsecode_possibilities.join("\n")