Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,81 @@
(() => {
'use strict';
// vanEck :: Int -> [Int]
const vanEck = n =>
reverse(
churchNumeral(n)(
xs => 0 < xs.length ? cons(
maybe(
0, succ,
elemIndex(xs[0], xs.slice(1))
),
xs
) : [0]
)([])
);
// TEST -----------------------------------------------
const main = () => {
console.log('VanEck series:\n')
showLog('First 10 terms', vanEck(10))
showLog('Terms 991-1000', vanEck(1000).slice(990))
};
// GENERIC FUNCTIONS ----------------------------------
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
// churchNumeral :: Int -> (a -> a) -> a -> a
const churchNumeral = n => f => x =>
Array.from({
length: n
}, () => f)
.reduce((a, g) => g(a), x)
// cons :: a -> [a] -> [a]
const cons = (x, xs) => [x].concat(xs)
// elemIndex :: Eq a => a -> [a] -> Maybe Int
const elemIndex = (x, xs) => {
const i = xs.indexOf(x);
return -1 === i ? (
Nothing()
) : Just(i);
};
// maybe :: b -> (a -> b) -> Maybe a -> b
const maybe = (v, f, m) =>
m.Nothing ? v : f(m.Just);
// reverse :: [a] -> [a]
const reverse = xs =>
'string' !== typeof xs ? (
xs.slice(0).reverse()
) : xs.split('').reverse().join('');
// showLog :: a -> IO ()
const showLog = (...args) =>
console.log(
args
.map(JSON.stringify)
.join(' -> ')
);
// succ :: Int -> Int
const succ = x => 1 + x;
// MAIN ---
return main();
})();

View file

@ -0,0 +1,108 @@
(() => {
"use strict";
// vanEck :: Int -> [Int]
const vanEck = n =>
// First n terms of the vanEck series.
[0].concat(mapAccumL(
([x, seen]) => i => {
const
prev = seen[x],
v = Boolean(prev) ? (
i - prev
) : 0;
return [
[v, (seen[x] = i, seen)], v
];
})(
[0, {}]
)(
enumFromTo(1)(n - 1)
)[1]);
// ----------------------- TEST ------------------------
const main = () =>
fTable(
"Terms of the VanEck series:\n"
)(
n => `${str(n - 10)}-${str(n)}`
)(
xs => JSON.stringify(xs.slice(-10))
)(
vanEck
)([10, 1000, 10000]);
// ----------------- GENERIC FUNCTIONS -----------------
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
// fTable :: String -> (a -> String) ->
// (b -> String) -> (a -> b) -> [a] -> String
const fTable = s =>
// Heading -> x display function ->
// fx display function ->
// f -> values -> tabular string
xShow => fxShow => f => xs => {
const
ys = xs.map(xShow),
w = Math.max(...ys.map(y => [...y].length)),
table = zipWith(
a => b => `${a.padStart(w, " ")} -> ${b}`
)(ys)(
xs.map(x => fxShow(f(x)))
).join("\n");
return `${s}\n${table}`;
};
// mapAccumL :: (acc -> x -> (acc, y)) -> acc ->
// [x] -> (acc, [y])
const mapAccumL = f =>
// A tuple of an accumulation and a list
// obtained by a combined map and fold,
// with accumulation from left to right.
acc => xs => [...xs].reduce(
([a, bs], x) => second(
v => bs.concat(v)
)(
f(a)(x)
),
[acc, []]
);
// second :: (a -> b) -> ((c, a) -> (c, b))
const second = f =>
// A function over a simple value lifted
// to a function over a tuple.
// f (a, b) -> (a, f(b))
([x, y]) => [x, f(y)];
// str :: a -> String
const str = x => x.toString();
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f =>
// A list constructed by zipping with a
// custom function, rather than with the
// default tuple constructor.
xs => ys => xs.map(
(x, i) => f(x)(ys[i])
).slice(
0, Math.min(xs.length, ys.length)
);
// MAIN ---
return main();
})();