UNPKG

ultra-mega-enumerator

Version:

Ultra Mega Enumerator is a lightweight library designed to enumerate various combinatorial objects.

83 lines 2.75 kB
"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