ml-combinations
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -0,1 +1,11 @@ | ||
<a name="1.1.0"></a> | ||
# [1.1.0](https://github.com/mljs/combinations/compare/v1.0.1...v1.1.0) (2018-07-26) | ||
### Bug Fixes | ||
* add codecov dependency ([52ec98d](https://github.com/mljs/combinations/commit/52ec98d)) | ||
<a name="1.0.1"></a> | ||
@@ -2,0 +12,0 @@ ## [1.0.1](https://github.com/mljs/combinations/compare/v1.0.0...v1.0.1) (2016-07-21) |
{ | ||
"name": "ml-combinations", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Generate all possible unordered samples of size m, without replacement, from a set of n objects", | ||
"main": "./src/index.js", | ||
"browser": "./lib/index.js", | ||
"files": [ | ||
"src" | ||
"src", | ||
"!src/__tests__", | ||
"lib" | ||
], | ||
"scripts": { | ||
"start": "rollup -c rollup.config.js --watch", | ||
"build": "rollup -c rollup.config.js", | ||
"eslint": "eslint src test", | ||
"eslint-fix": "npm run eslint -- --fix", | ||
"test": "npm run test-mocha && npm run eslint", | ||
"test-mocha": "mocha --require should --reporter mocha-better-spec-reporter" | ||
"test": "npm run test-only && npm run eslint", | ||
"test-only": "jest", | ||
"test-coverage": "jest --coverage", | ||
"test-travis": "npm run test-coverage && codecov", | ||
"prepublishOnly": "npm run build" | ||
}, | ||
@@ -33,8 +41,17 @@ "repository": { | ||
"devDependencies": { | ||
"eslint": "^3.1.0", | ||
"eslint-config-cheminfo": "^1.0.0", | ||
"mocha": "^2.5.3", | ||
"mocha-better-spec-reporter": "^3.0.2", | ||
"should": "^10.0.0" | ||
"babel-core": "^6.26.3", | ||
"babel-plugin-transform-runtime": "^6.23.0", | ||
"babel-preset-env": "^1.7.0", | ||
"codecov": "^3.0.2", | ||
"eslint": "^4.19.1", | ||
"eslint-config-cheminfo": "^1.17.4", | ||
"eslint-plugin-import": "^2.12.0", | ||
"eslint-plugin-jest": "^21.17.0", | ||
"eslint-plugin-no-only-tests": "^1.1.0", | ||
"jest": "^23.1.0", | ||
"rollup": "^0.63.4", | ||
"rollup-plugin-babel": "^3.0.7", | ||
"rollup-plugin-commonjs": "^9.1.3", | ||
"rollup-plugin-node-resolve": "^3.3.0" | ||
} | ||
} |
# combinations | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![David deps][david-image]][david-url] | ||
[![npm download][download-image]][download-url] | ||
Generate all possible unordered samples of size m, without replacement, from a set of n objects | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![Test coverage][codecov-image]][codecov-url] | ||
[![npm download][download-image]][download-url] | ||
Very low memory footprint even if the number of combinations to generate is high. | ||
Generate all possible [combinations](https://en.wikipedia.org/wiki/Combination), which are all the unordered samples of size k, without replacement, from a set of n objects. The number of k-combinations is equal to the binomial coefficient: | ||
![image](https://user-images.githubusercontent.com/4118690/40847651-445ec4c2-65bd-11e8-86df-58a5c0f16c73.png) | ||
Very low memory footprint even if the number of combinations to generate is high. Thank to generators, you can iterate over all possible samples, without creating a very large array. | ||
## Installation | ||
@@ -19,6 +21,7 @@ | ||
## Usage | ||
```js | ||
// the package exports a generator function | ||
const combinations = require('ml-combinations'); | ||
const options = {mode: 'index'}; | ||
const options = { mode: 'index' }; | ||
@@ -29,7 +32,7 @@ // the generator function returns an iterator | ||
// You can loop throw the iterator | ||
for(let combination of gen) { | ||
console.log(combination); | ||
for (let combination of gen) { | ||
console.log(combination); | ||
} | ||
// Or use destructuring | ||
// Or use destructuring, if you want to manipulate the array with all possible sample combinations | ||
console.log([...gen]); // [ [ 3, 2 ], [ 0, 2 ], [ 1, 2 ], [ 1, 2 ], [ 0, 2 ], [ 0, 1 ] ] | ||
@@ -44,5 +47,7 @@ | ||
## References | ||
Phillip J Chase, `Algorithm 382: Combinations of M out of N Objects \[G6\]', | ||
Communications of the Association for Computing Machinery 13:6:368 (1970). | ||
[To the article](http://dx.doi.org/10.1145/362384.362502) | ||
Communications of the Association for Computing Machinery 13:6:368 (1970). | ||
[To the article](http://dx.doi.org/10.1145/362384.362502) | ||
## License | ||
@@ -57,4 +62,6 @@ | ||
[david-image]: https://img.shields.io/david/mljs/combinations.svg?style=flat-square | ||
[codecov-url]: https://codecov.io/gh/mljs/combinations | ||
[codecov-image]: https://img.shields.io/codecov/c/github/mljs/combinations.svg?style=flat-square | ||
[david-url]: https://david-dm.org/mljs/combinations | ||
[download-image]: https://img.shields.io/npm/dm/ml-combinations.svg?style=flat-square | ||
[download-url]: https://npmjs.org/package/ml-combinations |
161
src/index.js
'use strict'; | ||
const defaultOptions = { | ||
mode: 'index' | ||
mode: 'index' | ||
}; | ||
module.exports = function *(M, N, options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
var a = new Array(N); | ||
var c = new Array(M); | ||
var b = new Array(N); | ||
var p = new Array(N + 2); | ||
var x, y, z; | ||
options = Object.assign({}, defaultOptions, options); | ||
var a = new Array(N); | ||
var c = new Array(M); | ||
var b = new Array(N); | ||
var p = new Array(N + 2); | ||
var x, y, z; | ||
// init a and b | ||
for (var i = 0; i < N; i++) { | ||
a[i] = i; | ||
if (i < N - M) b[i] = 0; | ||
else b[i] = 1; | ||
} | ||
// init a and b | ||
for (var i = 0; i < N; i++) { | ||
a[i] = i; | ||
if (i < N - M) b[i] = 0; | ||
else b[i] = 1; | ||
} | ||
// init c | ||
for (i = 0; i < M; i++) { | ||
c[i] = N - M + i; | ||
} | ||
// init c | ||
for (i = 0; i < M; i++) { | ||
c[i] = N - M + i; | ||
} | ||
// init p | ||
for (i = 0; i < p.length; i++) { | ||
if (i === 0) p[i] = N + 1; | ||
else if (i <= N - M) p[i] = 0; | ||
else if (i <= N) p[i] = i - N + M; | ||
else p[i] = -2; | ||
// init p | ||
for (i = 0; i < p.length; i++) { | ||
if (i === 0) p[i] = N + 1; | ||
else if (i <= N - M) p[i] = 0; | ||
else if (i <= N) p[i] = i - N + M; | ||
else p[i] = -2; | ||
} | ||
function twiddle() { | ||
var i, j, k; | ||
j = 1; | ||
while (p[j] <= 0) { | ||
j++; | ||
} | ||
function twiddle() { | ||
var i, j, k; | ||
j = 1; | ||
while (p[j] <= 0) | ||
j++; | ||
if (p[j - 1] === 0) { | ||
for (i = j - 1; i !== 1; i--) | ||
p[i] = -1; | ||
p[j] = 0; | ||
x = z = 0; | ||
p[1] = 1; | ||
y = j - 1; | ||
if (p[j - 1] === 0) { | ||
for (i = j - 1; i !== 1; i--) { | ||
p[i] = -1; | ||
} | ||
p[j] = 0; | ||
x = z = 0; | ||
p[1] = 1; | ||
y = j - 1; | ||
} else { | ||
if (j > 1) { | ||
p[j - 1] = 0; | ||
} | ||
do { | ||
j++; | ||
} | ||
while (p[j] > 0); | ||
k = j - 1; | ||
i = j; | ||
while (p[i] === 0) { | ||
p[i++] = -1; | ||
} | ||
if (p[i] === -1) { | ||
p[i] = p[k]; | ||
z = p[k] - 1; | ||
x = i - 1; | ||
y = k - 1; | ||
p[k] = -1; | ||
} else { | ||
if (i === p[0]) { | ||
return 0; | ||
} else { | ||
if (j > 1) | ||
p[j - 1] = 0; | ||
do | ||
j++; | ||
while (p[j] > 0); | ||
k = j - 1; | ||
i = j; | ||
while (p[i] === 0) | ||
p[i++] = -1; | ||
if (p[i] === -1) { | ||
p[i] = p[k]; | ||
z = p[k] - 1; | ||
x = i - 1; | ||
y = k - 1; | ||
p[k] = -1; | ||
} else { | ||
if (i === p[0]) { | ||
return 0; | ||
} else { | ||
p[j] = p[i]; | ||
z = p[i] - 1; | ||
p[i] = 0; | ||
x = j - 1; | ||
y = i - 1; | ||
} | ||
} | ||
p[j] = p[i]; | ||
z = p[i] - 1; | ||
p[i] = 0; | ||
x = j - 1; | ||
y = i - 1; | ||
} | ||
return 1; | ||
} | ||
} | ||
return 1; | ||
} | ||
if (options.mode === 'index') { | ||
yield c.slice(); | ||
while (twiddle()) { | ||
c[z] = a[x]; | ||
yield c.slice(); | ||
} | ||
} else if (options.mode === 'mask') { | ||
yield b.slice(); | ||
while (twiddle()) { | ||
b[x] = 1; | ||
b[y] = 0; | ||
yield b.slice(); | ||
} | ||
} else { | ||
throw new Error('Invalid mode'); | ||
if (options.mode === 'index') { | ||
yield c.slice(); | ||
while (twiddle()) { | ||
c[z] = a[x]; | ||
yield c.slice(); | ||
} | ||
} else if (options.mode === 'mask') { | ||
yield b.slice(); | ||
while (twiddle()) { | ||
b[x] = 1; | ||
b[y] = 0; | ||
yield b.slice(); | ||
} | ||
} else { | ||
throw new Error('Invalid mode'); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
36981
6
872
64
14
1