【问题标题】:Finding all even factorizations of a given number n - javascript python查找给定数字 n 的所有偶数分解 - javascript python
【发布时间】:2019-05-11 19:53:43
【问题描述】:

目前我正在实现一种算法,该算法依赖于查找给定数 n 的所有偶数分解,包括 n。

我已经尝试了一些东西,但总的来说我无法很好地处理这个问题。递归处理它也许是个好主意,但我对 javascript 还不是很好,尤其是在语言的高级方面可能会派上用场。

function evens(n) {
evens = []
for (var i = 2; i < n/2 - 1; i++){
    if (i % 2 != 0){
        continue;
    }
    else {
        if ((n/i) % 2 == 0) {
            evens.push([n/i, i])
        }
    }
}
return evens
}

这是一些可行的代码,但考虑到所有正确的基本情况,我还不能递归地实现它。 我还认为可以使用路径是偶数因素的树状结构来完成,但我的 cs 知识非常糟糕。

也欢迎使用 Python 提出建议,但最好使用 JavaScript。

只是为了让一切更清楚:例如 136 的所有偶数因式分解是 [[68, 2], [34, 2, 2], [34, 4], [136]]。

感谢您的帮助:)

【问题讨论】:

    标签: javascript python python-3.x number-theory factorization


    【解决方案1】:

    也许递归处理它是个好主意

    这是我在 Python 中尝试递归解决方案:

    def even_factorization(n):
        solutions = []
    
        def even_divisors(n):  # 136 generates [2, 4, 8, 34, 68, 136]
            return (d for d in range(2, n + 1, 2) if n % d == 0)
    
        def remove_similarities(array):  # [[2, 2, 34], [2, 34, 2], [34, 2, 2]] -> [[2, 2, 34]]
            return list(map(list, set(map(lambda a: tuple(sorted(a)), array))))
    
        for divisor in even_divisors(n):
            if divisor == n:
                solutions.append([divisor])
            else:
                for solution in even_factorization(n // divisor):
                    solutions.append([divisor] + solution)
    
        return remove_similarities(solutions)  # return 'solutions' to see raw data
    

    对于 136 次退货:

    [[2, 2, 34], [4, 34], [2, 68], [136]]
    

    对于 218960 返回:

    [[184, 1190], [8, 27370], [4, 54740], [2, 70, 1564], [56, 3910], [2, 2, 170, 322],
    [280, 782], [70, 3128], [4, 46, 1190], [2, 2, 34, 1610], [2, 14, 34, 230],
    [2, 14, 7820], [20, 34, 322], [10, 14, 34, 46], [14, 92, 170], [20, 46, 238],
    [218960], [2, 322, 340], [10, 68, 322], [34, 46, 140], [10, 14, 1564],
    [2, 10, 10948], [10, 92, 238], [4, 170, 322], [92, 2380], [14, 20, 782],
    [10, 21896], [238, 920], [28, 34, 230], [10, 28, 782], [2, 2, 46, 1190],
    [2, 28, 3910], [10, 34, 644], [34, 6440], [2, 92, 1190], [46, 4760], [2, 170, 644],
    [2, 68, 1610], [4, 70, 782], [340, 644], [2, 34, 46, 70], [2, 20, 5474],
    [14, 68, 230], [2, 34, 3220], [4, 34, 1610], [4, 10, 5474], [28, 7820],
    [14, 34, 460], [322, 680], [10, 46, 476], [2, 2, 54740], [4, 230, 238],
    [2, 2, 2, 27370], [34, 70, 92], [2, 140, 782], [14, 15640], [2, 10, 46, 238],
    [2, 10, 14, 782], [2, 14, 46, 170], [2, 238, 460], [136, 1610], [2, 2, 10, 5474],
    [20, 10948], [4, 14, 3910], [40, 5474], [2, 2, 70, 782], [2, 2, 230, 238],
    [230, 952], [68, 3220], [2, 46, 2380], [2, 230, 476], [2, 10, 34, 322],
    [140, 1564], [460, 476], [170, 1288], [2, 4, 27370], [46, 68, 70], [14, 46, 340],
    [2, 109480], [28, 46, 170], [2, 2, 14, 3910]]
    

    【讨论】:

    • 这和我想的差不多,干得好。我已经使用您的算法保存了大约 2000 个数字的偶数分解以继续处理它们,我可能会尝试在将来的某个时间在 javascript 中复制该算法。非常pythonian :)
    【解决方案2】:

    在 cdlane 正确指出我的解决方案中的缺陷后,我撤回了我原来的解决方案,并将 cdlane 优雅的 python 解决方案移植到 javascript。

    function even_factorization(n) {
      let solutions = [];
    
      function even_divisors(n) {
          var divisors = [];
          for (let i = 2; i <= n; i += 2) {
            if (n % i === 0) divisors.push(i);
          }
          return divisors;
      }
    
      function remove_similarities(combos) {
        for (let i = 0; i < combos.length; i++) {
          for (let j = i + 1; j < combos.length; j++) {
            if (combos[i].sort((a,b) => a - b).join(" ") === combos[j].sort((a,b) => a - b).join(" ")) {
              combos.splice(j--,1);
            }
          }
        }
        return combos;
      }
    
      even_divisors(n).forEach(divisor => {
        if (divisor === n)
          solutions.push([divisor]);
        else {
            even_factorization(n / divisor).forEach(solution => {
              solutions.push([divisor, ...solution]);
            });
        }
      });
    
      return remove_similarities(solutions);
    }
    

    以 218960 运行返回...

    • [[2,2,2,27370],[2,2,10,5474],[2,2,14,3910],[2,2,34,1610],[2,2,46 ,1190],[2,2,70,782],[2,2,170,322],[2,2,230,238],[2,2,54740],[2,4,27370],[2,10,14,782],[2 ,10,34,322],[2,10,46,238],[2,10,10948],[2,14,34,230],[2,14,46,170],[2,14,7820],[2,20 ,5474],[2,28,3910],[2,34,46,70],[2,34,3220],[2,46,2380],[2,68,1610],[2,70 ,1564],[2,92,1190],[2,140,​​782],[2,170,644],[2,230,476],[2,238,460],[2,322,340],[2,109480],[4,10,5474],[4,14 ,3910],[4,34,1610],[4,46,1190],[4,70,782],[4,170,322],[4,230,238],[4,54740],[8,27370],[10,14 ,34,46],[10,14,1564],[10,28,782],[10,34,644],[10,46,476],[10,68,322],[10,92,238],[10,21896], [14,20,782],[14,34,460],[14,46,340],[14,68,230],[14,92,170],[14,15640],[20,34,322],[20,46,238],[20] ,10948],[28,34,230],[28,46,170],[28,7820],[34,46,140],[34,70,92],[34,6440],[40,5474],[46 ,68,70],[46,4760],[56,3910],[68,3220],[70,3128],[92,2380],[136,1610],[140,1564],[170 ,1288],[184,1190],[230,952],[238,920],[280,782],[322,680],[340,644],[460,476],[218960]]

    ...运行 136 次返回...

    • [[2,2,34],[2,68],[4,34],[136]]

    【讨论】:

    • 如果我正确理解问题,[[184, 1190], [8, 27370], [4, 54740], ...] 甚至是 218960 的因式分解呢。
    • @cdlane 您理解正确,缺少一些解决方案。尽管我不知道你是否都得到了它们。这个问题太奇怪了,你在任何地方都找不到任何东西,因此很难验证大数字。
    • @cdlane,我为你优雅而完整的解决方案脱帽致敬!你的答案显然值得称赞。我冒昧地将您的 python 解决方案移植到 javascript,并在此处发布给任何感兴趣的人。
    • 感谢您的移植 (+1)。我没有跟上 JavaScript 的最新功能,所以它对我很有启发性,而且很容易理解,因为它很好地建立在我的解决方案之上。
    猜你喜欢
    • 1970-01-01
    • 2020-06-21
    • 2021-02-14
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多