【问题标题】:triangle numbers in pythonpython中的三角形数字
【发布时间】:2010-10-08 23:03:17
【问题描述】:

我正在尝试解决问题:

第一个有五百多个除数的三角形数的值是多少?

三角形数是数之和的序列中的一个数,即 1+2+3+4+5...

我很确定这是有效的代码,但我不知道,因为我的计算机计算它的时间太长了。有没有人知道如何使程序更快一点。
谢谢。

import math

def main():
    l = []
    one = 0
    a = 1
    b = 2
    while one == 0:
        a = a + b 
        b += 1
        for x in range(1, int(a/2 + 1)):
            if a % x == 0:
                l.append(x)
                if len(l) > 499:
                    print a 

if __name__ == '__main__':
    main()

【问题讨论】:

  • 请不要发布“one == 0”计算结果为真的代码。看着就心疼:|
  • 习惯它:-) 这是一个很好的比较。而在这个节目中,总是如此……
  • @Renze de Waal:你不能说while 1或至少while 1==1?变量不能叫running什么的吗?
  • 好的,但是为了你自己的理智,请尝试使用一致的缩进:)
  • while True: 似乎是正确的做法(我不是 Python 专家,但我的 Python 接受它)。

标签: python


【解决方案1】:

提示:

  • n-th 三角数的公式是什么?
  • nn+1 没有公因数(1 除外)。问题:给定nn+1 中的因子数如何计算n*(n+1) 中的因子数? n/2(n+1)(或 n(n+1)/2)呢?
  • 如果你知道n的所有质因数,如何计算n的除数?

如果您不想更改算法,则可以通过以下方式使其更快:

  • l.append 替换为factor_count += 1
  • 枚举到int(a**.5) 而不是a/2(在这种情况下使用factor_count += 2)。

【讨论】:

  • 你放弃了太多的解决方案。
  • 但是他给出了很好的指导! (不像上面的 Ghose 几乎是蛮力解决方案)。
  • +1:非常非常有用的提示。尤其是除数的主要因素——天才。
【解决方案2】:

你必须多思考,少用蛮力来解决 Project Euler 的问题。

在这种情况下,您应该调查三角形数有哪些和多少个除数。从头开始,寻找规律,尝试理解问题。

【讨论】:

    【解决方案3】:

    你没有更新one的值,所以你的程序永远不会结束。

    【讨论】:

    • 我认为这是@mark lincoln 对while True 的惯用语。考虑到问题while True 在这里是合适的。他只需要在print 之后添加break,修复几个错误,解决方案就会奏效(虽然太慢了)。
    • 我同意 - 打印后返回就可以了,至少就那部分而言。我个人尽量远离真实情况,因为我有忘记退货的坏习惯:P
    【解决方案4】:

    为了理智,你应该使用

    while True:
    

    并摆脱one

    【讨论】:

      【解决方案5】:

      首先,那些告诉你不能在一分钟内用蛮力解决这个问题的人是错误的。这种规模的问题的蛮力算法将在几秒钟内运行。

      其次,您发布的代码有几个问题,其中一些已经提到。

      • 一旦达到目标条件(当前为print a),您应该通过将one 设置为0 以外的某个值来终止循环。
      • 您永远不会重新初始化列表 (l = [])。这应该在您每次重新计算 ab 时完成,就在您进入 for 循环之前。
      • 问题要求第一个三角形数有超过五百个除数。您的终止条件应为if len(l) > 500:
      • 您可能不想在 for 循环中 print a,而是等到 while 循环完成。

      真正让你慢下来的是,对于每个三角形数a,你要检查每个值直到a / 2,看看它是否是一个除数。您只需检查不超过a 平方根的值。这样对于x 的每个值,如果x 是一个除数,您只需将xa / x 添加到列表中。

      这是您的代码,经过我上面概述的修改:

      import math
      
      def main():
          l = []
          one = 0
          a = 1
          b = 2
          while one == 0:
              a = a + b 
              b += 1
              l = []
      
              sqrt_a = int(math.sqrt(a))
      
              for x in range(1, sqrt_a + 1):
                  if a % x == 0:
                      l.append(x)
                      if x < math.sqrt(a):
                          l.append(a // x)
                      if len(l) > 500:
                          # print(a)
                          one = 1
      
          print(a, b, len(l))
      
      if __name__ == '__main__':
          main()
      

      您会看到它运行大约需要 5 或 6 秒,而这些修改不到一分钟。

      【讨论】:

        【解决方案6】:

        您当前的蛮力算法效率太低,无法在 1 分钟的 Project Euler 时间限制内解决此问题。相反,我建议查看除数函数:

        http://www.artofproblemsolving.com/Wiki/index.php/Divisor_function

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-11
          相关资源
          最近更新 更多