September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -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))
|
||||
);
|
||||
})();
|
||||
|
|
|
|||
68
Task/Combinations/JavaScript/combinations-7.js
Normal file
68
Task/Combinations/JavaScript/combinations-7.js
Normal 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)
|
||||
);
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue