2012年5月9日水曜日

プロジェクトオイラー Problem10

「プロジェクト オイラー」の問題をpythonでやってみます。

出典:
Project Euler(日本語翻訳サイト)
参考:
サイエンスもの置き場 プロジェクトオイラーを遊び倒すガイド(初級編)

Problem 10
10以下の素数の和は2 + 3 + 5 + 7 = 17である.
200万以下の全ての素数の和を計算しなさい.


私の解答例は以下のとおりです。
-----

def f(n):
	L = [2]
	for t in xrange(3, n+1, 2):
		for s in L:
			if not t%s: break
			elif t<s*s: L.append(t); break
	return sum(L)
	
print f(2000000)
-----

・関数f(n)はn以下の素数の和を返す関数です。

・L = [2]
 Lは素数リストです。初期値には最小の素数の2を設定します。

・for t in xrange(3, n+1, 2):
 3以上の奇数を素数候補tとします。tは3以上n+1未満の範囲で2とびの値です。

・for s in L:
 素数リストの要素を1つずつループ変数sに設定します。


if not t%s: break
 素数候補t ÷ 素数リストの要素s で割り切れるか判定します。
 %演算子は割り算の余りを計算します。
 if文では、0=False,それ以外=Trueなので、余りが無く割り切れる場合、素数sのループは終了させ次の素数候補tの値に進みます。

elif t<s*s: L.append(t); break
 elifは「else if」のことで、直前のif文でひっかからなかった場合にさらに追加して条件判定をする文です。
 素数候補tが何かの素数を因子に持つとすればその最大値はtの平方根です。
 例えば36は6x6なので6以下の数の積から成り立っています。(36=2x2x3x3)
 言い換えれば、割り算チェックで使っている素数sの平方(2乗)s*sがtを超えない、そのようなsで割ってチェックすればチェックは十分ということになります。
 そしてt<s*sが成り立つまでチェックが済めば、素数候補tは素数ですので、素数リストLに追加し、素数sのループは終了させ次の素数候補tの値に進みます。
 なお、「;」は複数の命令文を1行に書くときの連結子です。

もう少し判定条件を厳しくできれば処理時間が短縮できるはずです。

・return sum(L)
 こうして素数リストLにはn以下の素数が入ったので、sum関数で合計を計算しその値を返します。


解答はこのすぐ下の行です。文字の色を白にしてます。選択状態にすると見えます。

142913828922


(追記)
・20120716
 ソースコード部分にSyntaxHighlighterを導入。

0 件のコメント:

コメントを投稿