Decode the Morse Code

Decode the Morse Code

Solved in Ruby

Image for postMorse code!!!

For this particular problem I had to write a function that, when given a string of morse code, returns a translated version of that string. The only thing provided to me was a dictionary that I could access using the morse code as a key like so: `MORSE_CODE[‘.–‘]` Let?s get into it!

def decodeMorse(morseCode)end

So, I?m writing a function to translate a string of morse code. For this particular problem I can always assume that my input will be a string of morse code so I won?t be writing any tests to check and throw errors when an incorrect input is received.

First I want to take a look at exactly what my input looks like. Here is a sample input:

decode_morse(??. . -. ? . ? ? ..- -.. .?)

So, it is all one big string with spaces in between. Something else I forgot to mention earlier is that characters in words are separated by one single white space and words themselves are separated by three. It?s a little hard to see here but this will translate to ?HEY JUDE? when all is said and done.

I need to somehow get each word from this string and each character from each word and translate them all while keeping them properly sorted. Sounds tricky! I?m not super familiar with all the Ruby enumerable methods yet so I solved this a little more? JS style.

To begin with, I want to get all the words separated from each other. Therefore, I decided to split the input on any triple spaces like so:

morse_code.split(‘ ‘)

Our result is now an array containing two elements, the first being the first word in morse code and the second being the second word. Now, I want to work on decoding them. However, in order to translate each letter, I have to split up each word in a similar fashion. Therefore I will map over the array returned from my split and will split each word on a single white space since that is how characters are spaced out:

def decode_morse(morse_code) morse_code .split(‘ ‘) .map do |word| word.split(‘ ‘) endend

Now I have access to each character in a word so we can actually start the translating process! Each map call will return an array of the individual characters now so I can once again map over this newly returned array and decode each character one by one. Since I have access to the global dictionary I can just translate the letters by using key bracket notation:

def decode_morse(morse_code) morse_code .split(‘ ‘) .map do |word| word.split(‘ ‘).map { |char| MORSE_CODE[char] } endend

With that, we should be receiving an array of two arrays containing all the characters translated but not concatenated. Let me fix this by joining together our strings!

def decode_morse(morse_code) morse_code .split(‘ ‘) .map do |word| word.split(‘ ‘).map { |char| MORSE_CODE[char] }.join end .join(‘ ‘)end

With the first join method call I concatenate all the letters and return the fully translated string and then with the second I actually join the words all together with spaces in between them. With this we should have a successfully running morse decoder!

Really quickly though I would like to address a potential problem that I did end up facing. If you have a lot of consecutive white spaces, then you will most likely run into a problem with the decoder the way it is. Let?s say you have four white spaces at the beginning of the string and we split on three. Well, there will be one last white space remaining after splitting on three. Therefore, when we try to decode the empty string, nothing will change and it will be included in the final product. If you are writing tests and are expecting an exact result without extra white space then your test will fail. The solution I came up with was to filter out all white spaces after the initial split on three. That way there won?t be any remaining when we do the decoding and joining at the end! My final code ended up looking like this:

def decode_morse(morse_code) morse_code .split(‘ ‘) .select do |char| char != ” end .map do |word| word.split(‘ ‘).map { |char| MORSE_CODE[char] }.join end .join(‘ ‘)end

This code can definitely be refactored a lot using more specific Ruby enumerable methods like Strip but I wanted to show my initial code in this process.

If you?re also interested in solving these sorts of problems, head on over to Codewars and give them a go! They?re great practice for interview style questions; especially if you talk aloud through them to imitate that interview scenario.

17

No Responses

Write a response