Skip to content

Commit f0de894

Browse files
♻️ refactor(multicombinations): Extract indices generator.
1 parent a8c9fce commit f0de894

File tree

2 files changed

+48
-37
lines changed

2 files changed

+48
-37
lines changed

src/_multicombinations.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {list} from '@iterable-iterator/list';
2+
import {nrepeat} from '@iterable-iterator/repeat';
3+
4+
/**
5+
* Yields all k-multicombinations of {0, 1, ..., n-1}.
6+
*
7+
* @param {number} n
8+
* @param {number} r
9+
* @returns {IterableIterator<number[]>}
10+
*/
11+
export default function* multicombinations(n, r) {
12+
if (n === 0 && r > 0) return;
13+
14+
const indices = list(nrepeat(0, r));
15+
16+
yield indices;
17+
18+
while (true) {
19+
let i = r - 1;
20+
21+
// eslint-disable-next-line no-constant-condition
22+
while (true) {
23+
if (i < 0) return;
24+
25+
if (indices[i] !== n - 1) {
26+
const pivot = ++indices[i];
27+
28+
for (++i; i < r; ++i) indices[i] = pivot;
29+
30+
break;
31+
}
32+
33+
--i;
34+
}
35+
36+
yield indices;
37+
}
38+
}

src/multicombinations.js

+10-37
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {list} from '@iterable-iterator/list';
2-
import {pick} from '@iterable-iterator/map';
3-
import {nrepeat} from '@iterable-iterator/repeat';
2+
import {map, pick} from '@iterable-iterator/map';
3+
4+
import _multicombinations from './_multicombinations.js';
45

56
/**
67
* Yields all combinations, with repetitions, of each possible choice of
@@ -18,40 +19,12 @@ import {nrepeat} from '@iterable-iterator/repeat';
1819
* @param {number} r - The size of the combinations to generate.
1920
* @returns {IterableIterator}
2021
*/
21-
export default function* multicombinations(iterable, r) {
22+
const multicombinations = (iterable, r) => {
2223
const pool = list(iterable);
23-
const length = pool.length;
24-
25-
if (length === 0 && r > 0) {
26-
return;
27-
}
28-
29-
const indices = list(nrepeat(0, r));
30-
31-
yield list(pick(pool, indices));
32-
33-
while (true) {
34-
let i = r - 1;
35-
36-
// eslint-disable-next-line no-constant-condition
37-
while (true) {
38-
if (i < 0) {
39-
return;
40-
}
41-
42-
if (indices[i] !== length - 1) {
43-
const pivot = ++indices[i];
44-
45-
for (++i; i < r; ++i) {
46-
indices[i] = pivot;
47-
}
48-
49-
break;
50-
}
51-
52-
--i;
53-
}
24+
return map(
25+
(indices) => list(pick(pool, indices)),
26+
_multicombinations(pool.length, r),
27+
);
28+
};
5429

55-
yield list(pick(pool, indices));
56-
}
57-
}
30+
export default multicombinations;

0 commit comments

Comments
 (0)