diff --git a/hackerrank/morse-code-decoder.js b/hackerrank/morse-code-decoder.js index 5bdcb7b..f0c54b3 100644 --- a/hackerrank/morse-code-decoder.js +++ b/hackerrank/morse-code-decoder.js @@ -3,6 +3,9 @@ const regExMorseCodeRawDictionary = /\s*([A-Z0-9])(\s*)([.-]{1,6})\s*/; const regExContext = /^\s*([A-Z0-9]+)\s*$/; const regExMorseCode = /^\s*([.-]+)\s*$|^\s*([.-]+)\s*([.-]+)\s*$/; +// Maximum number of different morse characters for a candidate word to be considered a partial match +const PARTIAL_MATCH_TOLERANCE = 5; + function processData(input) { const { encodedWords, dictionary, context } = parseInput(input); @@ -106,7 +109,10 @@ function calculateMismatchIndicator(text1, text2) { function partialMatch(text1, text2) { const text = text1.length > text2.length ? text1 : text2; const partial = text1.length > text2.length ? text2 : text1; - return text.toLowerCase().indexOf(partial.toLowerCase()) > -1; + return ( + text.toLowerCase().indexOf(partial.toLowerCase()) > -1 && + Math.abs(text.length - partial.length) < PARTIAL_MATCH_TOLERANCE + ); } function buildPerfectMatch(perfectMatches) { @@ -120,7 +126,9 @@ function buildClosestMatch(partialMatches) { const closestMatch = partialMatches.sort( (a, b) => a.mismatch - b.mismatch )[0]; - return `${closestMatch.word}? ${closestMatch.mismatch}`; + return `${closestMatch.word}?${ + partialMatches.length > 1 ? " " + closestMatch.mismatch : "" + }`; } module.exports = { diff --git a/hackerrank/morse-code-decoder.test.js b/hackerrank/morse-code-decoder.test.js index 02a0615..6625eef 100644 --- a/hackerrank/morse-code-decoder.test.js +++ b/hackerrank/morse-code-decoder.test.js @@ -79,6 +79,12 @@ describe("morse code encoding", () => { const dictionary = buildTextToMorseDictionary(inputMorseCodeDictionary); expect(encode(text, dictionary)).toBe("..."); }); + + it("encoding example 2", () => { + const text = "WROTH"; + const dictionary = buildTextToMorseDictionary(inputMorseCodeDictionary); + expect(encode(text, dictionary)).toBe(".--.-.----...."); + }); }); describe("morse code decoding", () => { @@ -101,14 +107,12 @@ describe("morse code decoding", () => { }); describe("close match", () => { - it("given the morse code '.--.....--' (possibly 'WHAT'), and 'HAT' in the context, should return the best/closest valid word, plus a question mark and a mismatch indicator", () => { + it("given the morse code '.--.....--' (possibly 'WHAT'), and 'HAT' in the context, should return the best/closest valid word, plus a question mark", () => { const morse = ".--.....--"; const dictionary = buildTextToMorseDictionary(inputMorseCodeDictionary); const context = ["HAT"]; - // I don't remember exactly the rules for the computation of the mismatch indicator... - // I assume I have to show how many characters are different (3 in this case, comparing the morse from 'HAT' and 'WHAT'). - expect(decode(morse, dictionary, context)).toBe("HAT? 3"); + expect(decode(morse, dictionary, context)).toBe("HAT?"); }); }); @@ -144,13 +148,25 @@ describe("morse code decoding", () => { const stdout = outputData.split("-NEWLINE-"); expect(stdout[0]).toBe("WHAT!"); expect(stdout[1]).toBe("WHAT? 1"); - expect(stdout[2]).toBe("MALE? 4"); + expect(stdout[2]).toBe("MALE?"); expect(stdout[3]).toBe("No matching word found"); }); }); }); describe("HackerRank tests, based on provided input and expected output", () => { + it("test case 4", async () => { + const data = await readFileAsync( + "./morse-code-decoder.data.raw.txt", + "utf8" + ); + const input = parseInput(data); + + expect(decode(".--.-.----..", input.dictionary, input.context)).toBe( + "WROTH?" + ); + }); + it("test case 5", async () => { const data = await readFileAsync( "./morse-code-decoder.data.raw.txt",