# [SOLUTION] Morse Code (#121)

Thanks! That was a fun problem for a newbie. It was simple enough
to come up with a basic solution pretty rapidly, with several
opportunities to refine and experiment.

-Mark

# MORSE_SYMS: A dictionary mapping letters to their morse code.

MORSE_SYMS = { “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”, “–…” }

# Morse code.

def morse_words(s)
words = []
MORSE_SYMS.each_pair do |letter, morse|
#
# If the remaining string exactly matches a letter, then
# add that letter (by itself) as a result. This is how the
# recursion “bottoms out.”
#
if s == morse
words << letter
next
end

``````#
# Does the Morse code for the current letter match the start
# of the Morse code string?
#
l = morse.length
if s[0,l] == morse
#
# Generate the possibilities starting with the current letter.
#
morse_words(s[l..-1]).each do |w|
words << letter+w
end
end
``````

end
return words
end

# them with the given separator.

def to_morse(word, sep="|")
word.scan(/./).map { |c| MORSE_SYMS[c] }.join(sep)
end

if FILE == \$0

# pass /usr/share/dict/words.

dictionary = []
ARGV.each do |path|
end

# can test the “word in dictionary” case.

dictionary << “sofia”
dictionary << “eugenia”

# words to standard output.

\$stdin.each do |morse|
words = morse_words(morse.chomp)
words.sort! # Sorted output is easier to scan

``````#
# Find the length of the longest Morse code string
# so that we can line up columns nicely.
#
morse_max = words.map { |w| to_morse(w).length }.max

#
# Separate the words into two lists: those words which are
# in the dictionary, and those that aren't.
#
dict_words = words & dictionary
non_dict_words = words - dict_words

#
# Print the words.  I chose to print the dictionary words
# last, so they'd be easier to spot.
#
puts "Non-dictionary words:"
non_dict_words.each do |word|
print to_morse(word).ljust(morse_max), " => ", word, "\n"
end

puts "Dictionary words:"
dict_words.each do |word|
print to_morse(word).ljust(morse_max), " => ", word, "\n"
end
``````

end
end

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.