Created
November 8, 2020 20:26
-
-
Save sebinsua/97a8bca51188903d3199c1dad5694c96 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function letterFrequency(str) { | |
const uniques = {}; | |
for (let char of str) { | |
uniques[char] = uniques[char] ? ++uniques[char] : 1; | |
} | |
return uniques; | |
} | |
function letterFrequencyTemplate(uniques) { | |
return Object.entries(uniques) | |
.map(([char, count]) => `${char}${count}`) | |
.join(""); | |
} | |
function compress(str) { | |
let compressed = ""; | |
let lastChar; | |
let count; | |
for (let char of str) { | |
if (char === lastChar) { | |
count++; | |
continue; | |
} | |
if (lastChar) { | |
compressed += lastChar; | |
if (count > 1) { | |
compressed += `${count}`; | |
} | |
} | |
lastChar = char; | |
count = 1; | |
} | |
if (lastChar) { | |
compressed += lastChar; | |
if (count > 1) { | |
compressed += `${count}`; | |
} | |
} | |
return compressed; | |
} | |
function compress2(str) { | |
let compressed = ""; | |
function append(currentChar, count) { | |
compressed += currentChar; | |
if (count > 1) { | |
compressed += `${count}`; | |
} | |
} | |
let lastChar; | |
let count; | |
for (let char of str) { | |
if (char === lastChar) { | |
count++; | |
continue; | |
} | |
if (lastChar) append(lastChar, count); | |
lastChar = char; | |
count = 1; | |
} | |
if (lastChar) append(lastChar, count); | |
return compressed; | |
} | |
function compress3(str, separator = "") { | |
let compressed = ""; | |
function append(currentChar, count) { | |
if (compressed.length) { | |
compressed += separator; | |
} | |
compressed += currentChar; | |
if (count > 1) { | |
compressed += `${count}`; | |
} | |
} | |
let lastChar; | |
let count; | |
for (let char of str) { | |
if (char === lastChar) { | |
count++; | |
continue; | |
} | |
if (lastChar) append(lastChar, count); | |
lastChar = char; | |
count = 1; | |
} | |
if (lastChar) append(lastChar, count); | |
return compressed; | |
} | |
function* reverse(str) { | |
for (let idx = str.length - 1; idx >= 0; idx--) { | |
yield str[idx]; | |
} | |
} | |
function decompress(str) { | |
const NUMBER_REGEX = /\d/; | |
let decompressed = ""; | |
function append(currentChar, _count) { | |
const count = Number(_count.length ? _count : 1); | |
let chunk = currentChar; | |
if (count > 1) { | |
chunk = new Array(count).fill(currentChar).join(""); | |
} | |
decompressed = `${chunk}${decompressed}`; | |
} | |
let count = ""; | |
for (let char of reverse(str)) { | |
if (NUMBER_REGEX.test(char)) { | |
count = `${char}${count}`; | |
continue; | |
} | |
append(char, count); | |
count = ""; | |
} | |
return decompressed; | |
} | |
console.log(letterFrequencyTemplate(letterFrequency("aabbbcccccdd"))); | |
console.log(compress("aabbbcccccdd")); | |
console.log(compress2("aabbbcccccdd")); | |
console.log(compress3("xyyzzz", ",")); | |
console.assert( | |
compress3("aabbbcccccdd") === "a2b3c5d2", | |
"Could not compress correctly!" | |
); | |
// NOTE: | |
// Without a separator it is not possible to decompress strings with numbers in them | |
// because if you see something like 'a2b34', there could be 34 b characters at the | |
// end or 3 b characters followed by a 4 character. | |
// However, if there is a separator then these are distinct (e.g. 'a2,b34' and 'a2,b3,4'). | |
console.log(decompress("a2b3c5d2")); | |
console.log(decompress("x7y2z14")); | |
console.assert( | |
decompress("a2b3c5d2") === "aabbbcccccdd", | |
"Failed to decompress!" | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See also: https://gist.github.com/sebinsua/763998bee8efb3d7e1d04ec53dea5349