September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,47 +1,65 @@
(function (n) {
'use strict';
(() => {
// n -> [a] -> [[a]]
let comb = (n, xs) => {
if (n < 1) return [[]];
// combinations :: Int -> [a] -> [[a]]
const combinations = (n, xs) => {
const cmb_ = (n, xs) => {
if (n < 1) return [
[]
];
if (xs.length === 0) return [];
let h = xs[0],
const h = xs[0],
tail = xs.slice(1);
return cmb_(n - 1, tail)
.map(cons(h))
.concat(cmb_(n, tail));
};
return memoized(cmb_)(n, xs);
}
return comb(n - 1, tail)
.map((t) => [h].concat(t))
.concat(comb(n, tail));
},
// GENERIC FUNCTIONS ------------------------------------------------------
// 2 or more arguments
// curry :: Function -> Function
const curry = (f, ...args) => {
const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
function () {
return go(xs.concat(Array.from(arguments)));
};
return go([].slice.call(args, 1));
};
// cons :: a -> [a] -> [a]
const cons = curry((x, xs) => [x].concat(xs));
// Derive a memoized version of a function
// Function -> Function
memoized = (f) => {
let m = {};
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
return function (x) {
let args = [].slice.call(arguments),
strKey = args.join('-'),
v = m[strKey];
// Derive a memoized version of a function
// memoized :: Function -> Function
const memoized = f => {
let m = {};
return function (x) {
let args = [].slice.call(arguments),
strKey = args.join('-'),
v = m[strKey];
return (
(v === undefined) &&
(m[strKey] = v = f.apply(null, args)),
v
);
}
};
return (
(v === undefined) &&
(m[strKey] = v = f.apply(null, args)),
v
);
}
},
// show :: a -> String
const show = (...x) =>
JSON.stringify.apply(
null, x.length > 1 ? [x[0], null, x[1]] : x
);
range = (m, n) =>
Array.from({
length: (n - m) + 1
}, (_, i) => m + i);
return memoized(comb)(n, range(0, 4))
})(3);
return show(
memoized(combinations)(3, enumFromTo(0, 4))
);
})();

View file

@ -0,0 +1,68 @@
(() => {
'use strict';
// COMBINATIONS -----------------------------------------------------------
// comb :: Int -> Int -> [[Int]]
const comb = (m, n) => combinations(m, enumFromTo(0, n - 1));
// combinations :: Int -> [a] -> [[a]]
const combinations = (k, xs) =>
sort(filter(xs => k === xs.length, subsequences(xs)));
// GENERIC FUNCTIONS -----------------------------------------------------
// cons :: a -> [a] -> [a]
const cons = (x, xs) => [x].concat(xs);
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
// filter :: (a -> Bool) -> [a] -> [a]
const filter = (f, xs) => xs.filter(f);
// foldr (a -> b -> b) -> b -> [a] -> b
const foldr = (f, a, xs) => xs.reduceRight(f, a);
// isNull :: [a] -> Bool
const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;
// show :: a -> String
const show = x => JSON.stringify(x) //, null, 2);
// sort :: Ord a => [a] -> [a]
const sort = xs => xs.sort();
// stringChars :: String -> [Char]
const stringChars = s => s.split('');
// subsequences :: [a] -> [[a]]
const subsequences = xs => {
// nonEmptySubsequences :: [a] -> [[a]]
const nonEmptySubsequences = xxs => {
if (isNull(xxs)) return [];
const [x, xs] = uncons(xxs);
const f = (r, ys) => cons(ys, cons(cons(x, ys), r));
return cons([x], foldr(f, [], nonEmptySubsequences(xs)));
};
return nonEmptySubsequences(
(typeof xs === 'string' ? stringChars(xs) : xs)
);
};
// uncons :: [a] -> Maybe (a, [a])
const uncons = xs => xs.length ? [xs[0], xs.slice(1)] : undefined;
// TEST -------------------------------------------------------------------
return show(
comb(3, 5)
);
})();