任何人都能想到的最有效的算法是什么,给定一个自然数n,返回具有n 个正除数(包括 1 和x )的最小自然数x?例如,给定 4,算法应该得到 6(除数:1,2,3,6);即 6 是具有 4 个不同因子的最小数字。同样,给定 6,算法应该得到 12(除数:1、2、3、4、6、12);即 12 是具有 6 个不同因子的最小数字
就实际性能而言,我正在寻找一种可扩展的算法,它可以在每秒可以进行 10 7次计算的机器上在 2 秒内给出 10 20量级的答案。
任何人都能想到的最有效的算法是什么,给定一个自然数n,返回具有n 个正除数(包括 1 和x )的最小自然数x?例如,给定 4,算法应该得到 6(除数:1,2,3,6);即 6 是具有 4 个不同因子的最小数字。同样,给定 6,算法应该得到 12(除数:1、2、3、4、6、12);即 12 是具有 6 个不同因子的最小数字
就实际性能而言,我正在寻找一种可扩展的算法,它可以在每秒可以进行 10 7次计算的机器上在 2 秒内给出 10 20量级的答案。
http://www.primepuzzles.net/problems/prob_019.htm
b) Jud McCranie、TWA Baumann 和 Enoch Haga 发送基本相同的程序来找到给定d 的N(d) :
- 将d分解为他的主要因数的乘积:d = p 1 a 1 * p 2 a 2 *p 3 a 3 *...
- 将此分解转换为另一个算术等效分解,由非幂单调递减且不一定是素因数组成...(uf!...)d = p 1 a 1 * p 2 a 2 *p 3 a 3 *.. . = b 1 * b 2 * b 3 ...这样b 1 ≥ b 2 ≥ b 3 ...
您必须意识到,对于每个给定d
的 ,可以进行几个算术等价的因式分解:例如:
如果d = 16 = 2 4那么有 5 个等价分解: d = 2*2*2*2 = 4*2*2 = 4*4 = 8*2 = 16- N是对 d 的所有等价分解计算2 b 1 -1 * 3 b 2 -1 * 5 b 3 -1 * ...的最小结果。使用相同的示例:
N(16) = 这些 {2 * 3 * 5 * 7, 2 3 * 3 * 5, 2 3 * 3 3 , 2 7 * 3, 2 15 } = 2 3 * 3 * 5 = 120
更新:数字在 10 20左右,请注意同一页上引用的 Christian Bau 的注释。
//What is the smallest number with X factors?
function smallestNumberWithThisManyFactors(factorCount) {
Number.prototype.isPrime = function() {
let primeCandidate = this;
if(primeCandidate <= 1 || primeCandidate % 1 !== 0) return false
let i = 2;
while(i <= Math.floor(Math.sqrt(primeCandidate))){
if(primeCandidate%i === 0) return false;
i++;
}
return true;
}
Number.prototype.nextPrime = function() {
let currentPrime = this;
let nextPrimeCandidate = currentPrime + 1
while(nextPrimeCandidate < Infinity) {
if(nextPrimeCandidate.isPrime()){
return nextPrimeCandidate;
} else {
nextPrimeCandidate++;
}
}
}
Number.prototype.primeFactors = function() {
let factorParent = this;
let primeFactors = [];
let primeFactorCandidate = 2;
while(factorParent !== 1){
while(factorParent % primeFactorCandidate === 0){
primeFactors.push(primeFactorCandidate);
factorParent /= primeFactorCandidate;
}
primeFactorCandidate = primeFactorCandidate.nextPrime();
}
return primeFactors;
}
Number.prototype.factors = function() {
let parentNumber = this.valueOf();
let factors = []
let iterator = parentNumber % 2 === 0 ? 1 : 2
let factorCandidate = 1;
for(factorCandidate; factorCandidate <= Math.floor(parentNumber/2); factorCandidate += iterator) {
if(parentNumber % factorCandidate === 0) {
factors.push(factorCandidate)
}
}
factors.push(parentNumber)
return factors
}
Array.prototype.valueSort = function() {
return this.sort(function (a,b){ return a-b })
}
function clone3DArray(arrayOfArrays) {
let cloneArray = arrayOfArrays.map(function(arr) {
return arr.slice();
});
return cloneArray;
}
function does3DArrayContainArray(arrayOfArrays, array){
let aOA = clone3DArray(arrayOfArrays);
let a = array.slice(0);
for(let i=0; i<aOA.length; i++){
if(aOA[i].sort().join(',') === a.sort().join(',')){
return true;
}
}
return false;
}
function removeDuplicateArrays(combinations) {
let uniqueCombinations = []
for(let c = 0; c < combinations.length; c++){
if(!does3DArrayContainArray(uniqueCombinations, combinations[c])){
uniqueCombinations[uniqueCombinations.length] = combinations[c];
}
}
return uniqueCombinations;
}
function generateCombinations(parentArray) {
let generate = function(n, src, got, combinations) {
if(n === 0){
if(got.length > 0){
combinations[combinations.length] = got;
}
return;
}
for (let j=0; j<src.length; j++){
generate(n - 1, src.slice(j + 1), got.concat([src[j]]), combinations);
}
return;
}
let combinations = [];
for(let i=1; i<parentArray.length; i++){
generate(i, parentArray, [], combinations);
}
combinations.push(parentArray);
return combinations;
}
function generateCombinedFactorCombinations(primeFactors, primeFactorCombinations) {
let candidates = [];
for(let p=0; p<primeFactorCombinations.length; p++){
let product = 1;
let primeFactorsCopy = primeFactors.slice(0);
for(let q=0; q<primeFactorCombinations[p].length; q++){
product *= primeFactorCombinations[p][q];
primeFactorsCopy.splice(primeFactorsCopy.indexOf(primeFactorCombinations[p][q]), 1);
}
primeFactorsCopy.push(product);
candidates[candidates.length] = primeFactorsCopy.valueSort().reverse();
}
return candidates;
}
function determineMinimumCobination (candidates){
let minimumValue = Infinity;
let bestFactorCadidate = []
for(let y=0; y<candidates.length; y++){
let currentValue = 1;
let currentPrime = 2;
for(let z=0; z<combinedFactorCandidates[y].length; z++){
currentValue *= Math.pow(currentPrime,(combinedFactorCandidates[y][z])-1);
currentPrime = currentPrime.nextPrime();
}
if(currentValue < minimumValue){
minimumValue = currentValue;
bestFactorCadidate = combinedFactorCandidates[y];
}
}
return minimumValue;
}
let primeFactors = factorCount.primeFactors();
let primeFactorCombinations = removeDuplicateArrays(generateCombinations(primeFactors));
let combinedFactorCandidates = generateCombinedFactorCombinations(primeFactors, primeFactorCombinations);
let smallestNumberWithFactorCount = determineMinimumCobination(combinedFactorCandidates);
console.log('The smallest number with ' + factorCount + ' factors is: ')
console.log(smallestNumberWithFactorCount)
console.log('With these factors being: ')
console.log(smallestNumberWithFactorCount.factors())
return smallestNumberWithFactorCount;
}
smallestNumberWithThisManyFactors(10)