var nLoop = function (maxes, fn, dim, indices) { if (dim === void 0) { dim = 0; } if (indices === void 0) { indices = []; } if (dim < maxes.length) { var max = maxes[dim]; for (var i = 0; i <= max; i++) { indices[dim] = i; nLoop(maxes, fn, dim + 1, indices); } } else { fn(indices); } }; var FactorTable = /** @class */ (function () { function FactorTable(size) { var records = new Uint32Array(size * 2); // new Array(size); records[0] = 1; records[1] = 1; for (var n = 2; n <= size; n++) { var i = 2 * (n - 1); if (!records[i]) { records[i] = n; records[i + 1] = 1; for (var m = n + n; m <= size; m += n) { var j = 2 * (m - 1); if (!records[j]) { records[j] = n; records[j + 1] = m / n; } } } } this.size = size; this.records = records; } FactorTable.prototype.isPrime = function (n) { if (n > this.size) { return undefined; } return this.records[2 * n - 1] === 1; }; FactorTable.prototype.isPerfect = function (n) { if (n > this.size) { return undefined; } var factors = this.factors(n); var sum = -n; for (var _i = 0, factors_1 = factors; _i < factors_1.length; _i++) { var factor = factors_1[_i]; sum += factor; } return sum === n; }; FactorTable.prototype.factors = function (n) { if (n > this.size) { return undefined; } if (n === 1) { return [1]; } var primeFactorsList = this.primeFactors(n); var uniqueFactors = []; var uniqueFactorsCounts = []; var factorsList = []; for (var _i = 0, primeFactorsList_1 = primeFactorsList; _i < primeFactorsList_1.length; _i++) { var factor = primeFactorsList_1[_i]; var i = uniqueFactors.indexOf(factor); if (i === -1) { uniqueFactors.push(factor); uniqueFactorsCounts.push(1); } else { uniqueFactorsCounts[i]++; } } nLoop(uniqueFactorsCounts, function (powers) { var factor = 1; for (var i = 0; i < powers.length; i++) { factor *= Math.pow(uniqueFactors[i], powers[i]); } factorsList.push(factor); }); return factorsList; }; FactorTable.prototype.primeFactors = function (n) { if (n > this.size) { return undefined; } var records = this.records; var i = 2 * (n - 1); var list = [records[i]]; while (records[i + 1] !== 1) { i = 2 * (records[i + 1] - 1); list.push(records[i]); } return list; }; return FactorTable; }()); var ftStart = Date.now(); var ft = new FactorTable(35e6); console.log("Factor table built in " + (Date.now() - ftStart) + " ms"); var startTime = Date.now(); for (var n = 1; n <= ft.size; n++) { if (ft.isPerfect(n)) { console.log(n.toString(10) + " (" + (Date.now() - startTime) + " ms)"); } }