RosettaCodeData/Task/Cantor-set/JavaScript/cantor-set-1.js
2023-07-01 13:44:08 -04:00

88 lines
2 KiB
JavaScript

(() => {
"use strict";
// -------------- CANTOR BOOL-INT PAIRS --------------
// cantor :: [(Bool, Int)] -> [(Bool, Int)]
const cantor = xs => {
const go = ([bln, n]) =>
bln && 1 < n ? (() => {
const x = Math.floor(n / 3);
return [
[true, x],
[false, x],
[true, x]
];
})() : [
[bln, n]
];
return xs.flatMap(go);
};
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
cantorLines(5);
// --------------------- DISPLAY ---------------------
// cantorLines :: Int -> String
const cantorLines = n =>
take(n)(
iterate(cantor)([
[true, 3 ** (n - 1)]
])
)
.map(showCantor)
.join("\n");
// showCantor :: [(Bool, Int)] -> String
const showCantor = xs =>
xs.map(
([bln, n]) => (
bln ? (
"*"
) : " "
).repeat(n)
)
.join("");
// ---------------- GENERIC FUNCTIONS ----------------
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
// An infinite list of repeated
// applications of f to x.
function* (x) {
let v = x;
while (true) {
yield v;
v = f(v);
}
};
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => "GeneratorFunction" !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat(...Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// MAIN ---
return main();
})();