JavaScript随机数字组合算法故障求助:生成可被11整除的特定等式
问题修复:用1-5构建特定等式并判断整除性
需要用数字1、2、3、4、5构建等式:@ + ## + *** + &&&& + $$$$$(每个符号代表1-5中的唯一数字,每个数字仅用一次),判断计算结果是否能被11整除,满足条件则终止循环。但当前代码无法正常运行,以下是问题分析和修复方案。
原代码
let cypherNum = [1, 2, 3, 4, 5] function randomNum(min, max) { // min and max included return Math.floor(Math.random() * (max - min + 1) + min) } for (let n = 0; (n / 11 >= 0.0) && (Math.floor(n / 11) === n / 11) && n / 11 != Infinity; n++) { function sequence() { let selector1 = Math.round(randomNum(1, 5)) let number1 = cypherNum[selector1] cypherNum -= [selector1] let selector2 = Math.round(randomNum(1, 4)) let number2 = cypherNum[selector2] cypherNum -= [selector2] let selector3 = Math.round(randomNum(1, 3)) let number3 = cypherNum[Math.round(selector3)] cypherNum -= [selector3] let selector4 = Math.round(randomNum(1, 2)) let number4 = cypherNum[Math.round(randomNum(1, 2))] cypherNum -= [selector4] let number5 = cypherNum[1] cypherNum -= [1] let num = (number1) + (number2 * 11) + (number3 * 111) + (number4 * 1111) + (number5 * 11111) } console.log(sequence()) }
原代码的核心问题
- 数组删除方式错误:用
cypherNum -= [selector1]无法删除数组元素,正确的数组元素移除应该用splice()方法。 - 索引越界:数组索引从0开始,
randomNum(1,5)返回1-5的数字,直接作为索引访问会超出原数组(索引0-4)的范围,导致获取到undefined。 - 函数定义与返回值缺失:
sequence()定义在for循环内部属于冗余操作,且函数没有返回语句,调用后console.log只会输出undefined。 - 循环逻辑错误:for循环的条件是判断
n是否为11的倍数,但n从0开始递增,仅第一次循环满足条件,后续直接终止,无法实现多次生成序列的需求。 - 随机选择逻辑混乱:多次重复使用
Math.round处理随机数,且number4的选择使用两次随机,容易选中已删除元素的位置,导致数字获取错误。 - 数组未重置:每次生成序列后
cypherNum被修改,后续循环无法使用完整的1-5数组,无法生成有效排列。
修复方案
方案一:随机洗牌查找(适合直观演示)
用Fisher-Yates洗牌算法生成1-5的随机排列,计算结果并判断是否符合条件,找到即终止:
// 生成1-5的随机排列 function getRandomPermutation() { const arr = [1,2,3,4,5]; // Fisher-Yates洗牌算法 for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; } // 计算等式结果:@ + ## + *** + &&&& + $$$$$ function calculateResult(permutation) { return permutation[0] + permutation[1] * 11 + permutation[2] * 111 + permutation[3] * 1111 + permutation[4] * 11111; } // 循环查找符合条件的排列 while (true) { const perm = getRandomPermutation(); const result = calculateResult(perm); if (result % 11 === 0) { console.log(`找到符合条件的组合:${perm[0]} + ${perm[1]}${perm[1]} + ${perm[2]}${perm[2]}${perm[2]} + ${perm[3]}${perm[3]}${perm[3]}${perm[3]} + ${perm[4]}${perm[4]}${perm[4]}${perm[4]}${perm[4]}`); console.log(`计算结果:${result},可被11整除`); break; } }
方案二:遍历所有全排列(高效,仅120种可能)
直接生成1-5的所有全排列,逐一检查,找到符合条件的结果:
// 生成数组的全排列 function generatePermutations(arr) { const result = []; const backtrack = (current, remaining) => { if (remaining.length === 0) { result.push([...current]); return; } for (let i = 0; i < remaining.length; i++) { current.push(remaining[i]); backtrack(current, remaining.filter((_, idx) => idx !== i)); current.pop(); } }; backtrack([], arr); return result; } // 计算等式结果 function calculateResult(permutation) { return permutation[0] + permutation[1] * 11 + permutation[2] * 111 + permutation[3] * 1111 + permutation[4] * 11111; } // 遍历所有排列查找符合条件的结果 const allPermutations = generatePermutations([1,2,3,4,5]); for (const perm of allPermutations) { const result = calculateResult(perm); if (result % 11 === 0) { console.log(`找到符合条件的组合:${perm[0]} + ${perm[1]}${perm[1]} + ${perm[2]}${perm[2]}${perm[2]} + ${perm[3]}${perm[3]}${perm[3]}${perm[3]} + ${perm[4]}${perm[4]}${perm[4]}${perm[4]}${perm[4]}`); console.log(`计算结果:${result},可被11整除`); // 若要找所有符合条件的,可注释掉break break; } }
内容的提问来源于stack exchange,提问作者Yeetus
相关产品推荐
相关产品推荐

