【问题标题】:Efficient iteration in Python without using range不使用范围的 Python 中的高效迭代
【发布时间】:2018-07-06 18:43:06
【问题描述】:

我正在处理Project Euler 的第 45 题。提示如下:

三角形、五边形和六边形数由以下公式生成:

Tn= n(n+1) / 2

Pn= n(3 n − 1) / 2

Hn= n(2 n -1)

可以验证T285 = P165 = H143 = 40755。

找出下一个三角形数,它也是五边形和六边形。

我确实有一个可行的解决方案,但我在提供不依赖于 range 的任意值的答案时遇到了一些困难。

我当前的代码:

import collections
import time
start_time = time.time()

nums = []

for x in range(56000):
    t, p, h = (x * (x + 1) / 2) , x * (((3 * x) - 1) / 2), (x * ((2 * x) - 1))
    nums.extend([t, p, h])

j = [i for i, count in collections.Counter(nums).items() if count > 2]
pos = j.index(40755)
result = j[pos + 1]
print result
print("--- %s seconds ---" % (time.time() - start_time))

输出:

1533776805

--- 0.197566986084 秒 ---

如何在不使用range 的情况下在相同的时间内找到相同的答案?我想获得相同的输出,但不指定迭代次数。我尝试使用itertools.count,但在nums 列表中搜索符合上述条件的值需要很长时间。

提前致谢。

【问题讨论】:

  • @RBalasubramanian 只是因为我必须将任意值传递给范围,直到找到正确答案。
  • 经过进一步思考 - 我不明白这个问题(尤其是 itertools.count 是如何不起作用的)
  • Project Euler 45 here已经有很好的文档了

标签: python for-loop math


【解决方案1】:

更好的方法是遍历六边形数字的所有索引,然后看到这些数字也是五边形数字。 (正如@Mbo 在评论中告诉我的,所有六边形数字也是三角形数字,因此我们可以跳过该检查。)无需尝试任何更高的六边形数字。这是我解决这个问题的代码,它使用了一个没有任何rangewhile 循环。询问您是否需要更多解释从三角形或五边形数计算指数的公式。

"""Project Euler #0045 Triangular, pentagonal, and hexagonal

Triangle, pentagonal, and hexagonal numbers are generated by the
following formulae:

Triangle    T(n)=n(n+1)/2   1, 3, 6, 10, 15, ...
Pentagonal  P(n)=n(3n−1)/2  1, 5, 12, 22, 35, ...
Hexagonal   H(n)=n(2n−1)    1, 6, 15, 28, 45, ...

It can be verified that T(285) = P(165) = H(143) = 40755.

Find the next triangle number that is also pentagonal and hexagonal.

ANSWER: T(55385) = P(31977) = H(27693) = 1533776805
"""
from math import sqrt

_1_50 = 1 << 50  # 2**50 == 1,125,899,906,842,624
known_answer_hexagonal = 143

n_hex = known_answer_hexagonal
x = 1
while x <= _1_50:
    n_hex += 1
    x = n_hex * (2 * n_hex - 1)  # we know this is hexagonal

    sqrt_pen = sqrt(1 + 24 * x)
    if not sqrt_pen.is_integer():
        continue
    n_pen = (sqrt_pen + 1) / 6
    if not n_pen.is_integer():
        continue
    sqrt_tri = sqrt(1 + 8 * x)  # all hexagonal numbers are also triangular
    n_tri = (sqrt_tri - 1) / 2

    print('T({}) = P({}) = H({}) = {}'.format(
            int(n_tri), int(n_pen), int(n_hex), int(x)))
    break

在我的系统上,这需要 0.026999950408935547 秒,而您的代码需要 0.12299680709838867 秒,比我的代码长 4 倍以上。

【讨论】:

  • 不需要检查三角形 - 每个六边形也是三角形,索引为2*n_hex - 1
  • @MBo:哇,我没有意识到这一点!考虑到这一点,我会改进我的代码。谢谢!
猜你喜欢
  • 2021-07-01
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
相关资源
最近更新 更多