Skip to content

Instantly share code, notes, and snippets.

@robotlolita
Last active August 29, 2015 14:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robotlolita/1bc041ac6fb844ddc694 to your computer and use it in GitHub Desktop.
Save robotlolita/1bc041ac6fb844ddc694 to your computer and use it in GitHub Desktop.
function id(a) {
return a
}
function compose(f, g){ return function(x) {
return f(g(x))
}}
function partial(f, x) {
return function(y) {
return f(x, y)
}
}
function cons(a, as) {
return [a].concat(as)
}
function subsequences(xs) {
return cons([], nonEmptySubsequences(xs))
}
function nonEmptySubsequences(xs) {
return xs.length === 0? []
: /* otherwise */ cons([xs[0]], nonEmptySubsequences(xs.slice(1)).reduceRight(f(xs[0]), []))
function f(x){ return function(r, ys) {
return cons(ys, cons(cons(x, ys), r))
}}
}
function permutations(xs) {
return cons(xs, perms(xs, []))
function perms(ts, is) {
var t = ts[0], ts1 = ts.slice(1)
return ts.length === 0? []
: /* otherwise */ permutations(is).reduceRight(interleave(t, ts1), perms(ts1, cons(t, is)))
}
function interleave(t, ts){ return function(r, xs) {
return interleave1(t, ts, id, xs, r)[1]
}}
function interleave1(t, ts, f, xs, r) {
if (xs.length === 0) {
return [ts, r]
} else {
var y = xs[0], ys = xs.slice(1)
var p = interleave1(t, ts, compose(f, partial(cons, y)), ys, r)
var us = p[0], zs = p[1]
return [cons(y, us), cons(f(cons(t, cons(y, us))), zs)]
}
}
}
function flatten(xs) {
return [].concat.apply([], xs)
}
function flatmap(f, xs) {
return flatten(xs.map(f))
}
function combinationsOfLengthN(n, xs) {
return flatmap(permutations, subsequences(xs).filter(function(a){ return a.length === n }))
}
combinationsOfLengthN(1, [1, 2, 3, 4])
// => [[1], [2], [3], [4]]
combinationsOfLengthN(2, [1, 2, 3, 4])
// => [[1, 2], [2, 1], [1, 3], [3, 1], [2, 3], [3, 2], [1, 4], [4, 1], [2, 4], [4, 2], [3, 4], [4, 3]]
combinationsOfLengthN(3, [1, 2, 3, 4])
// => [[1, 2, 3], [2, 1, 3], [3, 2, 1], [2, 3, 1], [3, 1, 2], [1, 3, 2], [1, 2, 4], [2, 1, 4], [4, 2, 1], [2, 4, 1], [4, 1, 2], [1, 4, 2], [1, 3, 4], [3, 1, 4], [4, 3, 1], [3, 4, 1], [4, 1, 3], [1, 4, 3], [2, 3, 4], [3, 2, 4], [4, 3, 2], [3, 4, 2], [4, 2, 3], [2, 4, 3]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment