ultra-mega-enumerator
Version:
Ultra Mega Enumerator is a lightweight library designed to enumerate various combinatorial objects.
83 lines • 2.75 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PartitionEnumeration = void 0;
// src/enumerations/PartitionEnumeration.ts
const AbstractEnumeration_1 = require("./AbstractEnumeration");
class PartitionEnumeration extends AbstractEnumeration_1.AbstractEnumeration {
constructor(n) {
super();
this.next = null; // The next partition to return
if (n < 0) {
throw new Error("n must be non-negative.");
}
this.p = new Array(n + 1).fill(0);
this.p[0] = n; // Start with the partition [n]
this.k = 0; // Start at the first index
this.hasNext = n >= 0;
this.first = true;
this.nextPartition();
}
hasMoreElements() {
return this.next !== null;
}
nextElement() {
const partition = this.next.slice(); // Copy the current partition
this.nextPartition();
return partition;
}
nextPartition() {
if (!this.hasNext) {
throw new Error("No more partitions available.");
}
// Handle the first partition
if (this.first) {
this.first = false;
if (this.p[0] === 0) {
this.hasNext = false;
this.next = [];
return;
}
this.next = [this.p[0]];
return;
}
// Find the rightmost element that can be decreased
let rem = 0;
while (this.k >= 0 && this.p[this.k] === 1) {
rem += this.p[this.k];
this.k--;
}
// If k is negative, all elements were 1's and we are done
if (this.k < 0) {
this.hasNext = false;
this.next = null; // No more partitions
return;
}
// Decrease p[k] by 1
this.p[this.k]--;
// Calculate the new remainder to be distributed
rem += 1;
// Distribute the remainder among the following elements
let i = this.k + 1;
while (rem > this.p[this.k] && i < this.p.length) {
this.p[i] = this.p[this.k];
rem -= this.p[this.k];
i++;
}
// Assign the remaining remainder
if (i < this.p.length) {
this.p[i] = rem;
this.k = i; // Update the current index
}
// Construct the current partition to return
const currentPartition = [];
for (let j = 0; j <= this.k; j++) {
currentPartition.push(this.p[j]);
}
this.next = currentPartition;
}
static of(n) {
return new PartitionEnumeration(n);
}
}
exports.PartitionEnumeration = PartitionEnumeration;
//# sourceMappingURL=PartitionEnumeration.js.map