来自Project Euler的problem 45:
由三角形,五边形和六边形数字生成 以下公式:
三角形Tn = n x(n + 1)/ 2 1,3,6,10,15 ......
五角形Pn = n x(3n-1)/ 2 1,5,12,22,35 ...... 六边形Hn = n×(2n-1)1,6,15,28,45,......
可以证实T285 = P165 = H143 = 40755。
找到下一个三角形和六角形的三角形数字。
这是我的代码:
def triangle_generator():
n = 1
while True:
t = n * (n + 1) // 2
yield t
n += 1
def pentagonal_generator():
n = 1
while True:
p = n * ((3 * n) - 1) // 2
yield p
n += 1
def hexagonal_generator():
n = 1
while True:
h = n * ((2 * n) - 1)
yield h
n += 1
def tph():
tg = triangle_generator()
pg = pentagonal_generator()
hg = hexagonal_generator()
tg_temp_list = []
pg_temp_list = []
while True:
h = next(hg)
t = 0
p = 0
while t < h:
t = next(tg)
tg_temp_list.append(t)
while p < h:
p = next(pg)
pg_temp_list.append(p)
if h in tg_temp_list and h in pg_temp_list:
print("Found! {}".format(h))
else:
tg_temp_list = tg_temp_list[-2:]
pg_temp_list = pg_temp_list[-2:]
因此,产生一个六边形数字,然后填充两个临时列表 - 一个来自triangle_generator()
,另一个来自pentagonal_generator()
。然后,检查所产生的六边形数是否在这两个列表中。如果没有,临时列表将被清空,除了最后一个元素,产生另一个六边形数字,整个过程无限期重复。</ p>
我的问题:(假设纯粹的数学方法除外)Python是否提供了更方便(Pythonic)的方法来实现tph()
函数?
答案 0 :(得分:1)
也许更优雅,不确定更有效率。但是我的想法是,如果你可以合并迭代器,在每个pop上返回最低的#,即优先级队列,那么你的代码可以更清晰。
import heapq
def tph():
tg = triangle_generator()
pg = pentagonal_generator()
hg = hexagonal_generator()
count = 0
last_n = 0
for n in heapq.merge(tg, pg, hg):
if n == last_n:
count += 1
else:
count = 1
if count == 3:
print(n)
last_n = n
答案 1 :(得分:0)
这个问题可以通过计算和评估每个下一个三角形,五边形和六边形数字来解决,但是Project Euler问题主要是巧妙的数学和编程的良好组合。从wiki开始,我们知道每个六边形数字都是三角形数字。
因此,我们只需要遍历六边形数字,并在我们找到一个也是五边形数字时立即停止!通过一些简单的数学,我们发现当且仅当(sqrt(24 * candidate_value + 1) + 1) / 6
是整数时,数字才是五边形。
然后,问题变为以下代码:
import math
i = 144
while True:
hexagonal = i * (2 * i - 1)
if ((math.sqrt(24 * hexagonal + 1) + 1) / 6).is_integer():
print("Found it! The next occurence is {}".format(hexagonal))
break
i += 1