改め Objective Technician

はぐれ技術者のやりたい放題

SQLで素数サーチ

2010-09-10 00:44:31 | プログラミング
「割り切る数が存在しない」ことをEXISTS述語で表現する


自然数を,順序のない単なる数の集合として扱うところがいかにもSQLらしい.

import sqlite3

db = sqlite3.connect(":memory:");
c = db.cursor();

c.execute("CREATE TABLE Digits(n)");
c.executemany("INSERT INTO Digits VALUES(?)", [
    (0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,),
]);

numbers = "SELECT D1.n + 10 * D2.n AS n \
             FROM Digits D1 CROSS JOIN Digits D2";
c.execute("CREATE VIEW Numbers AS " + numbers);

divisor = "(SELECT * \
              FROM Numbers Divisor \
             WHERE Divisor.n <= Dividend.n / 2 \
AND Divisor.n != 1 \ AND Dividend.n % Divisor.n = 0)"; primeNumber = "SELECT n AS primeNumber \ FROM Numbers Dividend \ WHERE n > 1 \ AND NOT EXISTS " + divisor; c.execute(primeNumber + "order by primeNumber"); for row in c: print(row); c.close(); db.close();















Python だと1行で書けるけどな!
print([p for p in range(2, 100) if [1 for d in range(2, 1 + p // 2) if p % d == 0] == []]);

最新の画像もっと見る

3 コメント

コメント日が  古い順  |   新しい順
質問! (ok)
2010-09-17 12:14:24
[1 for d in range(2, 1 + p // 2) if p % d == 0]

なんで最初1なんだっけ?
返信する
定数 (kotaro)
2010-09-17 13:36:55
ループ内の処理を定数で書いておけば高速化できる可能性があるから。

ここでは割り切る数が存在するかを調べていて、その数が何であるかは問題にしない。
だから、1じゃなくても0でも他の型でももちろんdでもいいんだけど、ループの中でなるべく変数を使わないで済むんだったらそのほうがPythonインタプリタがうまいこと最適化して処理を速くしてくれるかもしれないから。
返信する
Unknown (ok)
2010-09-18 08:04:53
なるほどね!
サンクス。
返信する

コメントを投稿