4

For this project, I am trying to decode a given Morse code string. Encoded characters are separated by a single space and words are separated by three spaces. I am having a tough time getting past the word spaces. I keep getting "wordundefinedword".

decodeMorse = function(morseCode) {
    outPut = "";

    for (var i = 0; i < morseCode.split(" ").length; i++) {
        if (i === "   ") {
            outPut += " ";
        } else {
            outPut += MORSE_CODE[morseCode.split(" ")[i]];
        }

    }
    return outPut;
}

Example: "".... . -.--" "-- .- -."" -> "HEY MAN" Sorry for the weird quotes. It wouldn't show the spaces without the outer ones.

Allissia Baublet
  • 67
  • 1
  • 1
  • 4

9 Answers9

7

Here is a method that uses .map(), .split(), and .join().

function decodeMorse(morseCode) {
  var ref = { 
    '.-':     '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',
    '.----':  '1',
    '..---':  '2',
    '...--':  '3',
    '....-':  '4',
    '.....':  '5',
    '-....':  '6',
    '--...':  '7',
    '---..':  '8',
    '----.':  '9',
    '-----':  '0',
  };

  return morseCode
    .split('   ')
    .map(
      a => a
        .split(' ')
        .map(
          b => ref[b]
        ).join('')
    ).join(' ');
}

var decoded = decodeMorse(".-- --- .-. -..   .-- --- .-. -..");
console.log(decoded);
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
  • 4
    Your code has been stolen :) See 2nd screenshot at https://www.bleepingcomputer.com/news/security/new-phishing-attack-uses-morse-code-to-hide-malicious-urls/ – Luc VdV Feb 08 '21 at 15:35
  • 1
    @LucVdV My version is not even that good lol! It's an interesting article, though. Thanks for letting me know. :) – Joseph Marikle Feb 08 '21 at 20:19
5

Maybe have two loops nested instead. The outside loop splits your morse code by three spaces, and the inner loop splits the word by one space. That will parse out the letter, then you can map the alpha-numeric character by using an enum of the morse code letters.

// message = Halp! Morse code is driving me nuts!
var message = ".... .- .-.. .--. -·-·--     -- --- .-. ... .     -.-. --- -.. .     .. ...     -.. .-. .. ...- .. -. --.     -- .     -. ..- - ... -·-·--"; 
var alphabet = {  
   "-----":"0",
   ".----":"1",
   "..---":"2",
   "...--":"3",
   "....-":"4",
   ".....":"5",
   "-....":"6",
   "--...":"7",
   "---..":"8",
   "----.":"9",
   ".-":"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",
   "/":" ",
   "-.-.--":"!",
   ".-.-.-":".",
   "--..--":","
};
var messageConverted = [];

message.split("   ").map(function (word) {
    word.split(" ").map(function (letter) {
        messageConverted.push(alphabet[letter]);
    });
    messageConverted.push(" ");
});
 
console.log(messageConverted.join(""));

Or something like that. That enum is not complete (caps, punctuation), but you get the idea.

EricL
  • 941
  • 7
  • 8
  • An enum of the chars is listed in this post: http://stackoverflow.com/questions/26059170/using-javascript-to-encode-morsecode – EricL May 01 '17 at 20:58
  • 1
    You have different dots "·" for the the morse codes of "!.,", likely copied from someone else who thought having the dots on the same height is a good thing. I wanted a conversion table for some short snippet, was too lazy to write one myself obviously, googled, got here, copied your alphabet, and only later realized the issue. – ASDFGerte Jul 19 '18 at 18:19
  • Any significant reason why `.map()` is used here for the double loop instead of `.forEach()`? – damon Jan 13 '19 at 18:51
  • 1
    I just like using maps. Each has their own scope so it seems cleanest to me. But no. There's no reason a forEach couldn't be used. – EricL Jan 14 '19 at 19:07
4
decodeMorse = function( morseCode ) {
    return morseCode
             .split('   ') // get word code, 3 spaces apart
             .map(word => word
                           .split(' ') // get character code, 1 spaces apart
                           .map(character => MORSE_CODE[character]) // decode character
                           .join('') // join characters to word
              )
              .join(' ') // add spaces between words 
              .trim()
}

decodeMorse('.... . -.--   .--- ..- -.. .') // "HEY JUDE"
decodeMorse(' . ') // "E"

It works fine on codewars.com. If not codewars.com you need to define MORSE_CODE morse characters:

    const MORSE_CODE = {  
        "-----":"0",
        ".----":"1",
        "..---":"2",
        "...--":"3",
        "....-":"4",
        ".....":"5",
        "-....":"6",
        "--...":"7",
        "---..":"8",
        "----.":"9",
        ".-":"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",
        "-.-.--":"!",
        ".-.-.-":".",
        "--..--":","
    };

Hope my code can help you.

1

Sample Morse message:

var message = ".... .- .-.. .--. -.-.--     -- --- .-. ... .     -.-. --- -.. .     .. ...     -.. .-. .. ...- .. -. --.     -- .     -. ..- - ... -.-.--"; 

Morse dictionary:

var dictionary= {  
   "-----":"0",
   ".----":"1",
   "..---":"2",
   "...--":"3",
   "....-":"4",
   ".....":"5",
   "-....":"6",
   "--...":"7",
   "---..":"8",
   "----.":"9",
   ".-":"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",
   "-.-.--":"!",
   ".-.-.-":".",
   "--..--":","
};

Search for a pattern starting with . or - and translate it:

var representation = message.replace(/([.-]+[-.]*)/g, (_, x) =>dictionary [x]);
console.log(representation);
honk
  • 9,137
  • 11
  • 75
  • 83
Devmaleeq
  • 541
  • 6
  • 9
1

Another solution that based on 2 loops. The seperation of words in the morse code made by split(" ") - (with 3 separation signs) - which splits the morse code into words when it recognize 3 seperation signs. Now you have an array of x strings. In order to get an access to every element (a letter) in the morse code you should make another split by looping over the array of strings (you can use "map") but now with split(" ") -(with 1 separation signs). now you have an array that contain sub arrays which every one represent a word (in morse code of course). In order to loop over the dictionary of the morse code (an object) you can convert it into array by Object.keys etc and then find the specific letter (in morse) in the converted array (search the specific key).

an example of morse code:

 decodeMorse('.... . -.--   .--- ..- -.. .');
 //should return:"HEY JUDE"

the function:

decodeMorse = function(morseCode){ 
  var ind=0;
  var answer = [];
  const TOT_MORSE_CODE = {
  ".-": "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", ".---- 
  ":"1", "..---":"2", "...--":"3", "....-":"4", ".....":"5", 
  "-....":"6", "--...":"7", "---..":"8", "----.":"9", "----- 
  ":"0", "|":" "
  };

  const moerse_keys = Object.keys(TOT_MORSE_CODE);/*converting 
  the object into an array*/
  const moerse_values = Object.values(TOT_MORSE_CODE);
  var words_in_morse = morseCode.split ('   ');
  /*sperating the morse code by words*/
  var letters_in_morse = 
       words_in_morse.map(word => word.split(' '));
  /*sperating the morse code by letters for each word*/


  for (i=0 ; i<letters_in_morse.length ; i++) {
    for (j=0 ; j<letters_in_morse[i].length ; j++) {
       if ( moerse_keys.includes(letters_in_morse[i][j]) ) {
         ind = moerse_keys.indexOf( letters_in_morse[i][j] );
         answer.push(moerse_values[ind]);
       }
       if (j===letters_in_morse[i].length-1 ) { /*for seperate 
          words by ' '*/
          answer.push(' ');
       }
    }
  }

  answer.pop(); /*to remove the last ' ' (avoiding getting 
  "HEY JUDE ")*/
  return answer.join('').toUpperCase();
}
Nathan Barel
  • 348
  • 2
  • 14
0
const MorseCode = str => {

    var dictionary = {
        "-----": "0",
        ".----": "1",
        "..---": "2",
        "...--": "3",
        "....-": "4",
        ".....": "5",
        "-....": "6",
        "--...": "7",
        "---..": "8",
        "----.": "9",
        ".-": "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",
        "-.-.--": "!",
        ".-.-.-": ".",
        "--..--": ","
    };   
    var words = ''
    str.split(" ").forEach(cur => {
        if(cur === ""){
            words += " "
        }else{
            if(dictionary[cur]){
                words += dictionary[cur]
            }
        } 
    });
    return (words.split("  ")).join(" ")
}

const getPhrase = MorseCode(".... . -.--   .--- ..- -.. .")


console.log(getPhrase);
General Grievance
  • 4,555
  • 31
  • 31
  • 45
0

let STR = "hello".split("");
// % = space
let morse = ".-%-...%-.-.%-..%.%..-%--.%....%..%.---%-.-%.-..%--%-.%---%.--.%--.-%.-.%...%-%..-%...-%.--%-..-%-.--%--..".split("%");
let alphabet = "abcdefghijklmnopqrstuvwxyz".split("")

let output = [];

for(let i = 0; i < STR.length; i++){
    output.push(morse[alphabet.indexOf(STR[i])])
}

console.log(output.join(" "));

This is made for one lowercase word, as you can see, it converts text to morse code, instead of converting morse into text

0

A simple C# example can be found at https://github.com/zizwiz/Convert-Text-to-Morse-and-Play-it Allows text to be converted tp Morse and morse to be converted to Text and will also play Morse.

Uses spacings as follows

<summary>
Dot = 1 unit
Dash = 3 units

Between dots and dashes in letter = 1 unit
Between Chars = 3 units
Between words = 7 units
</summary>
user3884423
  • 556
  • 1
  • 5
  • 20
-1

Here is a method that uses .map(), .split(), .join() and .trim(). It works fine to me on codewars. The Morse code table is preloaded for you as a dictionary on MORSE_CODE.. so, no need to write the whole dictionary as I did in this example.

function decodeMorse(morseCode) {
  var letter = { 
    '.-':     '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',
    '.----':  '1',
    '..---':  '2',
    '...--':  '3',
    '....-':  '4',
    '.....':  '5',
    '-....':  '6',
    '--...':  '7',
    '---..':  '8',
    '----.':  '9',
    '-----':  '0',
  };

  return morseCode
    .split('   ')
    .map(
      a => a
        .split(' ')
        .map(
          b => letters[b]
        ).join('')
    ).join(' ')
    .trim() ;
}
var decoded = decodeMorse("   .-- --- .-. -..   .-- --- .-. -..");
console.log(decoded);