我正在做Project Euler Problem 12而我遇到了一个问题。这是我的代码:
def print_factors(x):
count = 0
for i in range(1, x + 1):
if x % i == 0:
count = count + 1
return count
count = 0
div = 0
while True:
if print_factors(count + count + 1) == 500:
print(count)
break;
count = count + 1
有更快的方法吗?这花了太长时间。
答案 0 :(得分:0)
对于每个三角形数字,您可以从2开始迭代素数。对于每次素数检查,可以分割数量的次数。例如,自28 / 2 = 14
和14 / 2 = 7
以来,28可以分为两次,分为两次。然后将当前除数的数量乘以+ 1.然后将剩余数量分配给数字并移至下一个素数。在prime <= number
时重复。下面是在实践中实现它的代码:
# Generate bunch of primes and cache them for efficiency
primes = [2, 3]
for i in xrange(5, 1000):
for j in primes:
if i % j == 0:
break
else:
primes.append(i)
i = 2
while True:
res = triangle = i * (i - 1) / 2
divisors = 1
for j in primes:
if j > triangle:
break
cur = 1
while triangle % j == 0:
triangle /= j
cur += 1
divisors *= cur
if divisors > 500:
break
i += 1
print res
答案 1 :(得分:0)
这是我的代码。
!/usr/bin/python
primes = [2]
def fp():
i=3
while i<10000:
for j in primes:
if i%j == 0:
break
else:
primes.append(i)
i+=1
def fac(n):
f={}
i = 0
while n > 1:
p=primes[i]
if p*p > n :
p=n
while n%p==0:
f[p]=f.get(p,0)+1
n/=p
i+=1
n=1
for i in f:
n*=f[i]+1
return n
from time import time
def f1():
t=time()
fp()
j=0
i=0
max = 0
while True:
i+=1
j+=i
f=fac(j)
if f >= 500:
break
print j,f
print time()-t
f1()
编辑:
素数:包含从2到最后素数小于10000的素数的列表(由fp构造)
fp:找到小于10000的所有素数并将它们存储在&#34; primes&#34;中。我们必须在此之后多次检查素数,因此预先找到并将它们存储在列表中将使整个过程更快。此功能很快,因为1.它只通过素数2.它停在目标数的sqrt。
fac:为给定数量的因子数量提供资金的函数。它比蛮力更好,因为它只是试图使用&#34; primes&#34;来找到所有的素因子。列表再次,停在目标号码的sqrt。在知道所有素数因子后,它使用某种组合算法计算因子的数量,这是每个不同素数因子的乘积。
例如:40 =(2 * 2 * 2)(5)然后40有(3(+1))(1(+1))= 8个因子
说明:您可以将其视为一个问题,即您有两组材料(示例中为2和5),并且您希望通过混合这些材料来查找可以生成的结果数。如果你专注于材料&#39; 2&#39;你可以选择只有一个&#39; 2&#39;得到2或2&#39; 2&#39;得到4或3 2得到&#39; 8&#39;或者没有&#39; 2&#39;根本得到1,所以你有3次+1的可能性。与&#39; 5&#39;相同,您可以通过选择和取消选择1 + 1种可能性。这就是(+1)的来源。
f1:主要功能。它跳转到下一个和下一个三角形数字,然后找到超过500个因子然后停止的那个,打印它所花费的时间。
答案 2 :(得分:0)
这个非常好的解决方案完全基于http://www.tech-thoughts-blog.com/2012/08/1-introduction-in-this-article-i-will.html的基础(仅有一些小的修正),rahmu提供了代码和对它的出色解释,所以这一切都归于他。无论是比原始代码还是其他解决方案更快,我都不确定。在我的机器上,它会在大约6秒内产生答案。
from collections import Counter
from operator import mul
from functools import reduce
def prime_factors(n):
"""
Generates all the prime factors of a positive integer n
:param n:
"""
d = 2
while n > 1:
while n % d == 0:
n /= d
yield d
d += 1
def format_prime(n):
"""
Returns a collection.Counter() built from the prime factors decomposition of n.
:param n:
"""
return Counter(prime_factors(n))
def prime_count(c):
""" c is a Counter() object holding the prime factor decomposition of an integer. It returns the total number of
divisors by applying the following formula:
Let N = a^x * b^y * c^z (a, b and c prime) and F(N) the total number of divisors of N.
F(N) = (x + 1) * (y + 1) * (c + 1)
:param c:
"""
return reduce(mul, (c[j] + 1 for j in c))
def triangle(k):
"""
k is an int. This function returns a collections.Counter that is the application of triangle(k) = k * (k+1) / 2.
:param k:
"""
a = format_prime(k)
b = format_prime(k+1)
c = a + b
c[2] -= 1 # This is equivalent to a division by 2
return c
if __name__ == "__main__":
i = 2
number_of_factors = 500
while prime_count(triangle(i)) <= number_of_factors:
i += 1
print(i * (i+1) // 2)