Humble numbers: Difference between revisions

Content added Content deleted
(→‎{{header|C sharp|C#}}: added direct generatio logarithms version)
(→‎{{header|JavaScript}}: updated primitives)
Line 1,818: Line 1,818:
'use strict';
'use strict';


// -------------------HUMBLE NUMBERS-------------------
// ------------------ HUMBLE NUMBERS -------------------


// humbles :: () -> [Int]
// humbles :: () -> [Int]
Line 1,835: Line 1,835:
};
};


// ------------------------TEST------------------------
// ----------------------- TEST ------------------------
// main :: IO ()
// main :: IO ()
const main = () => {
const main = () => {
Line 1,863: Line 1,863:




// -----------------GENERIC FUNCTIONS------------------
// ----------------- GENERIC FUNCTIONS -----------------


// chunksOf :: Int -> [a] -> [[a]]
// chunksOf :: Int -> [a] -> [[a]]
const chunksOf = n => xs =>
const chunksOf = n =>
enumFromThenTo(0)(n)(
xs => enumFromThenTo(0)(n)(
xs.length - 1
xs.length - 1
).reduce(
).reduce(
Line 1,873: Line 1,873:
[]
[]
);
);



// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
const compose = (...fs) =>
x => fs.reduceRight((a, f) => f(a), x);
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);



// concat :: [[a]] -> [a]
// concat :: [[a]] -> [a]
Line 1,887: Line 1,894:
return unit.concat.apply(unit, xs);
return unit.concat.apply(unit, xs);
})() : [];
})() : [];



// enumFromThenTo :: Int -> Int -> Int -> [Int]
// enumFromThenTo :: Int -> Int -> Int -> [Int]
const enumFromThenTo = x1 => x2 => y => {
const enumFromThenTo = x1 =>
const d = x2 - x1;
x2 => y => {
return Array.from({
const d = x2 - x1;
length: Math.floor(y - x2) / d + 2
return Array.from({
}, (_, i) => x1 + (d * i));
length: Math.floor(y - x2) / d + 2
}, (_, i) => x1 + (d * i));
};
};



// enumFromTo :: Int -> Int -> [Int]
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m => n =>
const enumFromTo = m =>
Array.from({
n => Array.from({
length: 1 + n - m
length: 1 + n - m
}, (_, i) => m + i);
}, (_, i) => m + i);



// fTable :: String -> (a -> String) -> (b -> String)
// fTable :: String -> (a -> String) -> (b -> String)
Line 1,917: Line 1,928:
).join('\n');
).join('\n');
};
};



// fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
// fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
Line 1,928: Line 1,940:
};
};



// group :: [a] -> [[a]]
// group :: Eq a => [a] -> [[a]]
const group = xs => {
const group = xs => {
// A list of lists, each containing only equal elements,
// such that the concatenation of these lists is xs.
const go = xs =>
const go = xs =>
0 < xs.length ? (() => {
0 < xs.length ? (() => {
Line 1,939: Line 1,954:
) : [xs];
) : [xs];
})() : [];
})() : [];
return go(xs);
const v = go(list(xs));
return 'string' === typeof xs ? (
v.map(x => x.join(''))
) : v;
};
};


// justifyRight :: Int -> Char -> String -> String
// justifyRight :: Int -> Char -> String -> String
const justifyRight = n => cFiller => s =>
const justifyRight = n =>
n > s.length ? (
// The string s, preceded by enough padding (with
// the character c) to reach the string length n.
s.padStart(n, cFiller)
c => s => n > s.length ? (
s.padStart(n, c)
) : s;
) : s;


Line 1,958: Line 1,978:
) : Infinity;
) : Infinity;



// map :: (a -> b) -> [a] -> [b]
const map = f => xs =>
// list :: StringOrArrayLike b => b -> [a]
(Array.isArray(xs) ? (
const list = xs =>
// xs itself, if it is an Array,
// or an Array derived from xs.
Array.isArray(xs) ? (
xs
xs
) : xs.split('')).map(f);
) : Array.from(xs);


// map :: (a -> b) -> [a] -> [b]
const map = f =>
// The list obtained by applying f
// to each element of xs.
// (The image of xs under f).
xs => [...xs].map(f);


// str :: a -> String
// str :: a -> String
Line 1,994: Line 2,025:


// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f => xs => ys => {
const zipWith = f =>
// Use of `take` and `length` here allows zipping with non-finite lists
const
// i.e. generators like cycle, repeat, iterate.
lng = Math.min(length(xs), length(ys)),
as = take(lng)(xs),
xs => ys => {
bs = take(lng)(ys);
const n = Math.min(length(xs), length(ys));
return Array.from({
return Infinity > n ? (
length: lng
(([as, bs]) => Array.from({
}, (_, i) => f(as[i])(
length: n
bs[i]
}, (_, i) => f(as[i])(
));
bs[i]
)))([xs, ys].map(
};
compose(take(n), list)
))
) : zipWithGen(f)(xs)(ys);
};


// MAIN ---
// MAIN ---