-
Notifications
You must be signed in to change notification settings - Fork 0
/
4kyu-decodeMorseCodeAdvanced.js
107 lines (81 loc) · 4.46 KB
/
4kyu-decodeMorseCodeAdvanced.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'use strict';
// Source: https://www.codewars.com/kata/54b72c16cd7f5154e9000457/
// DESCRIPTION:
// In this kata you have to write a Morse code decoder for wired electrical
// telegraph.
// Electric telegraph is operated on a 2-wire line with a key that, when pressed,
// connects the wires together, which can be detected on a remote station. The
// Morse code encodes every character being transmitted as a sequence of "dots"
// (short presses on the key) and "dashes" (long presses on the key).
// When transmitting the Morse code, the international standard specifies that:
// "Dot" – is 1 time unit long.
// "Dash" – is 3 time units long.
// Pause between dots and dashes in a character – is 1 time unit long.
// Pause between characters inside a word – is 3 time units long.
// Pause between words – is 7 time units long.
// However, the standard does not specify how long that "time unit" is. And in
// fact different operators would transmit at different speed. An amateur person
// may need a few seconds to transmit a single character, a skilled professional
// can transmit 60 words per minute, and robotic transmitters may go way faster.
// For this kata we assume the message receiving is performed automatically by the
// hardware that checks the line periodically, and if the line is connected (the
// key at the remote station is down), 1 is recorded, and if the line is not
// connected (remote key is up), 0 is recorded. After the message is fully
// received, it gets to you for decoding as a string containing only symbols 0 and
// 1.
// For example, the message HEY JUDE, that is ···· · −·−− ·−−− ··− −·· · may be
// received as follows:
// 1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011
// As you may see, this transmission is perfectly accurate according to the
// standard, and the hardware sampled the line exactly two times per "dot".
// That said, your task is to implement two functions:
// Function decodeBits(bits), that should find out the transmission rate of the
// message, correctly decode the message to dots ., dashes - and spaces (one
// between characters, three between words) and return those as a string. Note that
// some extra 0's may naturally occur at the beginning and the end of a message,
// make sure to ignore them. Also if you have trouble discerning if the particular
// sequence of 1's is a dot or a dash, assume it's a dot.
// 2. Function decodeMorse(morseCode), that would take the output of the previous
// function and return a human-readable string.
// NOTE: For coding purposes you have to use ASCII characters . and -, not Unicode
// characters.
// The Morse code table is preloaded for you (see the solution setup, to get its
// identifier in your language).
// All the test strings would be valid to the point that they could be reliably
// decoded as described above, so you may skip checking for errors and exceptions,
// just do your best in figuring out what the message is!
function decodeBits(bits) {
bits = trimBits(bits);
let timeUnitLong = calcTimeUnitLong(bits);
if (!timeUnitLong) return bits;
let dash = new RegExp('1'.repeat(3 * timeUnitLong), 'g');
let dot = new RegExp('1'.repeat(timeUnitLong), 'g');
let betweenWords = new RegExp('0'.repeat(7 * timeUnitLong), 'g');
let betweenChars = new RegExp('0'.repeat(3 * timeUnitLong), 'g');
let insideChar = new RegExp('0'.repeat(timeUnitLong), 'g');
let morseCode = bits.replace(dash, '-');
morseCode = morseCode.replace(dot, '.');
morseCode = morseCode.replace(betweenWords, ' ');
morseCode = morseCode.replace(betweenChars, ' ');
morseCode = morseCode.replace(insideChar, '');
return morseCode;
}
function trimBits(bits) {
return bits.replace(/^0*(.*?)0*$/, '$1');
}
function calcTimeUnitLong(bits) {
let sequencesArray = bits.match(/1+|0+/g);
if (!sequencesArray) return 0;
let minSequence = sequencesArray.reduce((a, b) => a <= b ? a : b);
return minSequence.length;
}
function decodeMorse(morseCode) {
let encodedWordsArray = morseCode.split(' ');
let decodedWordsArray = encodedWordsArray.map(decodeMorseWord);
return decodedWordsArray.join(' ');
}
function decodeMorseWord(decodedWord) {
let decodedCharsArray = decodedWord.split(' ');
let encodedCharsArray = decodedCharsArray.map(char => MORSE_CODE[char]);
return encodedCharsArray.join('');
}