@specs-feup/lara
Version:
A js port of the popular framework for building source-to-source compilers
64 lines (52 loc) • 1.72 kB
text/typescript
import Numbers from "../Numbers.js";
import SequentialCombinations from "./SequentialCombinations.js";
/**
* Generates sequential sequences of combinations, according to the given number of elements.
*/
export default class Combinations extends SequentialCombinations {
elements: number[];
combinationSize: number;
numCombinations: number;
currentCombinations: number = 0;
constructor(elements: number[], combinationSize: number) {
super(elements.length);
this.elements = elements;
this.combinationSize = combinationSize;
// Number of combinations
// n!/(r!(n−r)!)
const nFact = Numbers.factorial(elements.length);
const rFact = Numbers.factorial(combinationSize);
const nrDiff = elements.length - combinationSize;
const nrDiffFact = Numbers.factorial(nrDiff);
this.numCombinations = nFact / (rFact * nrDiffFact);
}
/**
* @returns The next sequence
*/
next() {
// Check if there are combinations left
if (!this.hasNext()) {
throw new Error(
`Combinations.next: Reached maximum number of combinations (${this.numCombinations})`
);
}
// Get new values, until one with length of combinationSize appear
let sequence: number[] = [];
while (sequence.length !== this.combinationSize) {
sequence = super.next();
}
// Found sequence, create combination
const combination = [];
for (const index of sequence) {
combination.push(this.elements[index]);
}
this.currentCombinations++;
return combination;
}
/**
* @returns True if there are stil combinations to generate
*/
hasNext(): boolean {
return this.currentCombinations < this.numCombinations;
}
}