今日、私はProject Eulerで与えられた問題を解決しました。これは問題番号 10で、Python プログラムが結果を表示するのに7 時間かかりました。しかし、そのフォーラム自体で、lassevkという名前の人がこれに対する解決策を投稿し、わずか4 秒しかかかりませんでした。また、そのフォーラムはディスカッション フォーラムではないため、この質問をそのフォーラムに投稿することはできません。したがって、この質問を非建設的なものとしてマークしたい場合は、これについて考えてください。
marked = [0] * 2000000
value = 3
s = 2
while value < 2000000:
if marked[value] == 0:
s += value
i = value
while i < 2000000:
marked[i] = 1
i += value
value += 2
print s
誰かがこのコードを理解している場合は、できるだけ簡単に説明してください。
これは、計算に7時間かかった私のコードです(以下の回答で言及されているエラトステネスのふるい手法と同じロジックも使用したと思います):
import time
start = time.clock()
total = 0
limit = 2000000
KnownPrime = set([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
53, 59, 61, 67, 71])
KnownPrime.update(set([73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,
131, 137, 139, 149, 151, 157, 163, 167, 173]))
suspected = set(range(2, limit+1)) # list of suspected prime numbers
for p in KnownPrime:
if p <= limit:
total += p
suspected.difference_update(set(range(p, limit+1, p)))
for i in suspected:
k = i/2
if k % 2 == 0: k += 1
PrimeCheck = set(range(k, 2, -2))
PrimeCheck.difference_update(KnownPrime)
for j in PrimeCheck:
if i % j == 0:
break
if i % j:
total += i
print time.clock() - start
print total
では、なぜそんなに時間がかかったのか誰か教えてください。
最後に、これが私のリファクタリングされたコードです。2 秒で結果を表示できるようになりました。
import math
import __builtin__
sum = __builtin__.sum
def is_prime(num):
if num < 2: return False
if num == 2: return True
if num % 2 == 0: return False
for i in range(3, int(math.sqrt(num)) + 1, 2):
if num % i == 0: return False
return True
def sum_prime(num):
if num < 2: return 0
sum_p = 2
core_primes = []
suspected = set(range(3, num + 1, 2))
for i in range(3, int(math.sqrt(num)) + 1, 2):
if is_prime(i): core_primes.append(i)
for p in core_primes:
sum_p += p
suspected.difference_update(set(range(p, num + 1, p)))
return sum(suspected) + sum_p
print sum_prime(2000000)
そして、これがその視覚化です。