From: "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com>
Date: April 21, 2007 5:01:15 PM CDT
To: james@grayproductions.net
Subject: Re: [QUIZ] Morse Code (#121)1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.Hi James, I'm not sure when the 48 hours expire, but as tomorrow I will not
be able to access email and I wanted to send as early as possible I would
appreciate if you could forward my "solution" as soon as you see fit.I say "solution" since it's late here (I'm in Spain) and I'm tired, so I haven't
made formal tests, just some manual tests and I think it's correct.Sorry if this is not appropriate, as this is my first try at Ruby Quiz
and my first post to ruby-talk :-).Also, I'm fairly new to Ruby, only programming little things to learn,
but nothing serious. So I'd appreciate any feedback you have on my
Ruby. For example I had a little of hard time to get the dups right,
because I was always storing the same string so other iterations were
modifying the same object: hope I have it right !!Morse code is a way to encode telegraphic messages in a series of long and short
sounds or visual signals. During transmission, pauses are used to group letters
and words, but in written form the code can be ambiguous.This week's quiz is to write program that displays all possible translations for
ambiguous words provided in code.OK. So here's my solution. I just start slicing characters from the
begining of the input to check all the combinations that match with a
letter, then try everything that can match the starting of the rest,
etc, until there's no rest to match. I have stored the mapping between
Morse characters and the letters in a hash to look them up easily:letters = {".-" => "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"}input = ARGV[0]
# Start a queue with the empty translation and the input as rest to translate
queue = [["", input]]# Calculate the min and max length of the keys to
# slice from the rest to translate only from min to max
sorted_keys = letters.keys.sort_by {|x| x.length}
min_length = sorted_keys[0].length
max_length = sorted_keys[-1].lengthanswers =
while (!queue.empty?) do
process = queue.shift
translation = process[0]
rest = process[1]
# Try to slice from the min key length to the max key length
# but not more than the resting length
up_to = (max_length < rest.length ? max_length : rest.length)
min_length.upto(up_to) do |length|
current_rest = rest.dup
current_translation = translation.dup
# Get the first characters from the rest that may form a letter
next_morse = current_rest.slice!(0..length-1)
letter = letters[next_morse]
if (letter)
# If there is a letter corresponding to those characters add it
# to the translation
current_translation << letter
# If there's nothing left to translate we have an answer
if (current_rest.empty?)
answers << current_translation
# Else add what's left to translate to the queue
else
queue << [current_translation, current_rest]
end
end
end
endputs answers
-------------------------------Thanks.
Jesus Gabriel y Galan.
···
Begin forwarded message:
On 4/20/07, Ruby Quiz <james@grayproductions.net> wrote: