combinationsReplacement recurses on x.slice(i, x.length), which at i = 0 is as long as the input, so the only exit left is the k === 1 base case. For k <= 0 the counter starts below that case and moves away from it, and the recursion overflows the stack. The sibling combinations recurses on x.slice(i + 1, x.length), runs out of input and returns [] for the same arguments. Guard the non-positive group size up front so both functions agree.
42 lines
1.3 KiB
JavaScript
42 lines
1.3 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import * as ss from "../index.js";
|
|
|
|
describe("combinations", function () {
|
|
it("generates 1 permutation", function () {
|
|
assert.deepEqual(ss.combinationsReplacement(Object.freeze([1]), 1), [
|
|
[1]
|
|
]);
|
|
});
|
|
it("generates combinations of 1,2 choosing two at a time, with replacement", function () {
|
|
assert.deepEqual(ss.combinationsReplacement(Object.freeze([1, 2]), 2), [
|
|
[1, 1],
|
|
[1, 2],
|
|
[2, 2]
|
|
]);
|
|
});
|
|
it("returns no combinations when choosing zero at a time", function () {
|
|
assert.deepEqual(
|
|
ss.combinationsReplacement(Object.freeze([1, 2, 3]), 0),
|
|
[]
|
|
);
|
|
});
|
|
it("returns no combinations for a negative group size", function () {
|
|
assert.deepEqual(
|
|
ss.combinationsReplacement(Object.freeze([1, 2, 3]), -1),
|
|
[]
|
|
);
|
|
});
|
|
it("agrees with combinations on non-positive group sizes", function () {
|
|
const x = Object.freeze([1, 2, 3]);
|
|
assert.deepEqual(
|
|
ss.combinationsReplacement(x, 0),
|
|
ss.combinations(x, 0)
|
|
);
|
|
assert.deepEqual(
|
|
ss.combinationsReplacement(x, -1),
|
|
ss.combinations(x, -1)
|
|
);
|
|
});
|
|
});
|