69 lines
1.9 KiB
JavaScript
69 lines
1.9 KiB
JavaScript
(() => {
|
|
'use strict';
|
|
|
|
// HARSHADS ---------------------------------------------------------------
|
|
|
|
// nHarshads :: Int -> [Int]
|
|
const nHarshads = n => {
|
|
|
|
// isHarshad :: Int -> Bool
|
|
const isHarshad = n => 0 === n % sum(digitList(n));
|
|
|
|
return until(
|
|
dct => dct.nth === n,
|
|
dct => {
|
|
const
|
|
next = succ(dct.i),
|
|
blnHarshad = isHarshad(next);
|
|
return {
|
|
i: next,
|
|
hs: blnHarshad ? dct.hs.concat(next) : dct.hs,
|
|
nth: dct.nth + (blnHarshad ? 1 : 0)
|
|
};
|
|
}, {
|
|
i: 0,
|
|
hs: [],
|
|
nth: 0
|
|
}
|
|
)
|
|
.hs;
|
|
};
|
|
|
|
// GENERIC FUNCTIONS ------------------------------------------------------
|
|
|
|
// digitList :: Int -> [Int]
|
|
const digitList = n =>
|
|
n > 0 ? [n % 10].concat(digitList(Math.floor(n / 10))) : [];
|
|
|
|
// dropWhile :: (a -> Bool) -> [a] -> [a]
|
|
const dropWhile = (p, xs) => {
|
|
let i = 0;
|
|
for (let lng = xs.length;
|
|
(i < lng) && p(xs[i]); i++) {}
|
|
return xs.slice(i);
|
|
};
|
|
|
|
// head :: [a] -> a
|
|
const head = xs => xs.length ? xs[0] : undefined;
|
|
|
|
// a -> String
|
|
const show = x => JSON.stringify(x, null, 2);
|
|
|
|
// succ :: Int -> Int
|
|
const succ = x => x + 1
|
|
|
|
// sum :: (Num a) => [a] -> a
|
|
const sum = xs => xs.reduce((a, x) => a + x, 0);
|
|
|
|
// until :: (a -> Bool) -> (a -> a) -> a -> a
|
|
const until = (p, f, x) => {
|
|
const go = x => p(x) ? x : go(f(x));
|
|
return go(x);
|
|
};
|
|
|
|
// TEST -------------------------------------------------------------------
|
|
return show({
|
|
firstTwenty: nHarshads(20),
|
|
firstOver1000: head(dropWhile(x => x <= 1000, nHarshads(1000)))
|
|
});
|
|
})();
|