Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
220
Task/Attractive-numbers/JavaScript/attractive-numbers.js
Normal file
220
Task/Attractive-numbers/JavaScript/attractive-numbers.js
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// attractiveNumbers :: () -> Gen [Int]
|
||||
const attractiveNumbers = () =>
|
||||
// An infinite series of attractive numbers.
|
||||
filter(
|
||||
compose(isPrime, length, primeFactors)
|
||||
)(enumFrom(1));
|
||||
|
||||
|
||||
// ----------------------- TEST -----------------------
|
||||
// main :: IO ()
|
||||
const main = () =>
|
||||
showCols(10)(
|
||||
takeWhile(ge(120))(
|
||||
attractiveNumbers()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// ---------------------- PRIMES ----------------------
|
||||
|
||||
// isPrime :: Int -> Bool
|
||||
const isPrime = n => {
|
||||
// True if n is prime.
|
||||
if (2 === n || 3 === n) {
|
||||
return true
|
||||
}
|
||||
if (2 > n || 0 === n % 2) {
|
||||
return false
|
||||
}
|
||||
if (9 > n) {
|
||||
return true
|
||||
}
|
||||
if (0 === n % 3) {
|
||||
return false
|
||||
}
|
||||
return !enumFromThenTo(5)(11)(
|
||||
1 + Math.floor(Math.pow(n, 0.5))
|
||||
).some(x => 0 === n % x || 0 === n % (2 + x));
|
||||
};
|
||||
|
||||
|
||||
// primeFactors :: Int -> [Int]
|
||||
const primeFactors = n => {
|
||||
// A list of the prime factors of n.
|
||||
const
|
||||
go = x => {
|
||||
const
|
||||
root = Math.floor(Math.sqrt(x)),
|
||||
m = until(
|
||||
([q, _]) => (root < q) || (0 === (x % q))
|
||||
)(
|
||||
([_, r]) => [step(r), 1 + r]
|
||||
)([
|
||||
0 === x % 2 ? (
|
||||
2
|
||||
) : 3,
|
||||
1
|
||||
])[0];
|
||||
return m > root ? (
|
||||
[x]
|
||||
) : ([m].concat(go(Math.floor(x / m))));
|
||||
},
|
||||
step = x => 1 + (x << 2) - ((x >> 1) << 1);
|
||||
return go(n);
|
||||
};
|
||||
|
||||
|
||||
// ---------------- GENERIC FUNCTIONS -----------------
|
||||
|
||||
// chunksOf :: Int -> [a] -> [[a]]
|
||||
const chunksOf = n =>
|
||||
xs => enumFromThenTo(0)(n)(
|
||||
xs.length - 1
|
||||
).reduce(
|
||||
(a, i) => a.concat([xs.slice(i, (n + i))]),
|
||||
[]
|
||||
);
|
||||
|
||||
|
||||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
const compose = (...fs) =>
|
||||
fs.reduce(
|
||||
(f, g) => x => f(g(x)),
|
||||
x => x
|
||||
);
|
||||
|
||||
|
||||
// enumFrom :: Enum a => a -> [a]
|
||||
function* enumFrom(x) {
|
||||
// A non-finite succession of enumerable
|
||||
// values, starting with the value x.
|
||||
let v = x;
|
||||
while (true) {
|
||||
yield v;
|
||||
v = 1 + v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// enumFromThenTo :: Int -> Int -> Int -> [Int]
|
||||
const enumFromThenTo = x1 =>
|
||||
x2 => y => {
|
||||
const d = x2 - x1;
|
||||
return Array.from({
|
||||
length: Math.floor(y - x2) / d + 2
|
||||
}, (_, i) => x1 + (d * i));
|
||||
};
|
||||
|
||||
|
||||
// filter :: (a -> Bool) -> Gen [a] -> [a]
|
||||
const filter = p => xs => {
|
||||
function* go() {
|
||||
let x = xs.next();
|
||||
while (!x.done) {
|
||||
let v = x.value;
|
||||
if (p(v)) {
|
||||
yield v
|
||||
}
|
||||
x = xs.next();
|
||||
}
|
||||
}
|
||||
return go(xs);
|
||||
};
|
||||
|
||||
|
||||
// ge :: Ord a => a -> a -> Bool
|
||||
const ge = x =>
|
||||
// True if x >= y
|
||||
y => x >= y;
|
||||
|
||||
|
||||
// justifyRight :: Int -> Char -> String -> String
|
||||
const justifyRight = n =>
|
||||
// The string s, preceded by enough padding (with
|
||||
// the character c) to reach the string length n.
|
||||
c => s => n > s.length ? (
|
||||
s.padStart(n, c)
|
||||
) : s;
|
||||
|
||||
|
||||
// last :: [a] -> a
|
||||
const last = xs =>
|
||||
// The last item of a list.
|
||||
0 < xs.length ? xs.slice(-1)[0] : undefined;
|
||||
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
// Returns Infinity over objects without finite
|
||||
// length. This enables zip and zipWith to choose
|
||||
// the shorter argument when one is non-finite,
|
||||
// like cycle, repeat etc
|
||||
(Array.isArray(xs) || 'string' === typeof xs) ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
|
||||
|
||||
// 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 => (
|
||||
Array.isArray(xs) ? (
|
||||
xs
|
||||
) : xs.split('')
|
||||
).map(f);
|
||||
|
||||
|
||||
// showCols :: Int -> [a] -> String
|
||||
const showCols = w => xs => {
|
||||
const
|
||||
ys = xs.map(str),
|
||||
mx = last(ys).length;
|
||||
return unlines(chunksOf(w)(ys).map(
|
||||
row => row.map(justifyRight(mx)(' ')).join(' ')
|
||||
))
|
||||
};
|
||||
|
||||
|
||||
// str :: a -> String
|
||||
const str = x =>
|
||||
x.toString();
|
||||
|
||||
|
||||
// takeWhile :: (a -> Bool) -> Gen [a] -> [a]
|
||||
const takeWhile = p => xs => {
|
||||
const ys = [];
|
||||
let
|
||||
nxt = xs.next(),
|
||||
v = nxt.value;
|
||||
while (!nxt.done && p(v)) {
|
||||
ys.push(v);
|
||||
nxt = xs.next();
|
||||
v = nxt.value
|
||||
}
|
||||
return ys;
|
||||
};
|
||||
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs =>
|
||||
// A single string formed by the intercalation
|
||||
// of a list of strings with the newline character.
|
||||
xs.join('\n');
|
||||
|
||||
|
||||
// until :: (a -> Bool) -> (a -> a) -> a -> a
|
||||
const until = p => f => x => {
|
||||
let v = x;
|
||||
while (!p(v)) v = f(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue