Run-Length Encoding For Strings
Encode repeated characters into compact count-letter runs and decode them back with strict validation of malformed input.
Code
export function runLengthEncode(input) {
if (typeof input !== "string") throw new TypeError("input must be a string");
const characters = [...input];
let encoded = "";
for (let index = 0; index < characters.length; ) {
let run = 1;
while (index + run < characters.length && characters[index + run] === characters[index]) {
run += 1;
}
encoded += run + characters[index];
index += run;
}
return encoded;
}
export function runLengthDecode(encoded) {
if (typeof encoded !== "string") throw new TypeError("encoded must be a string");
const token = /(\d+)([\s\S])/gu;
let decoded = "";
let consumed = 0;
for (const match of encoded.matchAll(token)) {
if (match.index !== consumed) throw new SyntaxError("invalid run-length token");
const count = Number(match[1]);
if (!Number.isSafeInteger(count) || count <= 0) {
throw new RangeError("run length must be a positive safe integer");
}
decoded += match[2].repeat(count);
consumed = match.index + match[0].length;
}
if (consumed !== encoded.length) throw new SyntaxError("invalid run-length token");
return decoded;
}Report a problem with this exampleOpens a pre-filled issue on GitHub.