diff --git a/package.json b/package.json index 38c77ae..5cf568f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@combinatorics/n-combinations", "description": "Set n-combinations for JavaScript", - "version": "0.0.1", + "version": "0.0.2", "license": "AGPL-3.0", "author": "make-github-pseudonymous-again", "homepage": "https://computational-combinatorics.github.io/n-combinations", diff --git a/src/_combinations.js b/src/_combinations.js new file mode 100644 index 0000000..88b87df --- /dev/null +++ b/src/_combinations.js @@ -0,0 +1,38 @@ +import {list} from '@iterable-iterator/list'; +import {range} from '@iterable-iterator/range'; + +/** + * Yields all k-subsets of {0, 1, ..., n-1}. + * + * @param {number} n + * @param {number} k + * @returns {IterableIterator} + */ +export default function* _combinations(n, k) { + if (k > n) return; + + const indices = list(range(0, k, 1)); + + yield indices; + + while (true) { + let i = k - 1; + + // eslint-disable-next-line no-constant-condition + while (true) { + if (i < 0) return; + + if (indices[i] !== i + n - k) { + let pivot = ++indices[i]; + + for (++i; i < k; ++i) indices[i] = ++pivot; + + break; + } + + --i; + } + + yield indices; + } +} diff --git a/src/combinations.js b/src/combinations.js index 05e2615..5d85e5e 100644 --- a/src/combinations.js +++ b/src/combinations.js @@ -1,6 +1,7 @@ import {list} from '@iterable-iterator/list'; -import {pick} from '@iterable-iterator/map'; -import {range} from '@iterable-iterator/range'; +import {map, pick} from '@iterable-iterator/map'; + +import _combinations from './_combinations.js'; /** * Yields all combinations of each possible choice of r elements @@ -16,42 +17,14 @@ import {range} from '@iterable-iterator/range'; * * @param {Iterable} iterable - The input iterable. * @param {number} r - The size of the combinations to generate. - * @returns {IterableIterator} + * @returns {IterableIterator} */ -export default function* combinations(iterable, r) { +const combinations = (iterable, r) => { const pool = list(iterable); - const length = pool.length; - - if (r > length) { - return; - } - - const indices = list(range(0, r, 1)); - - yield list(pick(pool, indices)); - - while (true) { - let i = r - 1; - - // eslint-disable-next-line no-constant-condition - while (true) { - if (i < 0) { - return; - } - - if (indices[i] !== i + length - r) { - let pivot = ++indices[i]; - - for (++i; i < r; ++i) { - indices[i] = ++pivot; - } - - break; - } - - --i; - } + return map( + (indices) => list(pick(pool, indices)), + _combinations(pool.length, r), + ); +}; - yield list(pick(pool, indices)); - } -} +export default combinations; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy