RosettaCodeData/Task/Run-length-encoding/JavaScript/run-length-encoding-4.js

52 lines
1.4 KiB
JavaScript

(() => {
'use strict';
// runLengthEncode :: String -> [(Int, Char)]
const runLengthEncoded = s =>
group(s.split('')).map(
cs => [cs.length, cs[0]]
);
// runLengthDecoded :: [(Int, Char)] -> String
const runLengthDecoded = pairs =>
pairs.map(([n, c]) => c.repeat(n)).join('');
// ------------------------TEST------------------------
const main = () => {
const
xs = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWW' +
'WWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW',
ys = runLengthEncoded(xs);
console.log('From: ', show(xs));
[ys, runLengthDecoded(ys)].forEach(
x => console.log(' -> ', show(x))
)
};
// ----------------------GENERIC-----------------------
// group :: [a] -> [[a]]
const group = xs => {
// A list of lists, each containing only equal elements,
// such that the concatenation of these lists is xs.
const go = xs =>
0 < xs.length ? (() => {
const
h = xs[0],
i = xs.findIndex(x => h !== x);
return i !== -1 ? (
[xs.slice(0, i)].concat(go(xs.slice(i)))
) : [xs];
})() : [];
return go(xs);
};
// show :: a -> String
const show = JSON.stringify;
// MAIN ---
return main();
})();