Skip to content

Commit

Permalink
refactor(morse-code-decoder): partial match tolerance
Browse files Browse the repository at this point in the history
  • Loading branch information
jebarsoba committed Mar 30, 2022
1 parent 9f99f0a commit c5ce031
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
12 changes: 10 additions & 2 deletions hackerrank/morse-code-decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand All @@ -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 = {
Expand Down
26 changes: 21 additions & 5 deletions hackerrank/morse-code-decoder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand All @@ -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?");
});
});

Expand Down Expand Up @@ -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",
Expand Down

0 comments on commit c5ce031

Please sign in to comment.