与えられた数 n
が素数なら True
,そうでなければ False
を返す関数を作ってみましょう。
基本は順に割っていけばよいはずです。
def isprime(n): if n < 2: return False for i in range(2, n): if n % i == 0: return False return True
動作確認してみましょう。
for i in range(2, 100): if isprime(i): print(i, "は素数")
上は 2 以上 n
未満の整数すべてで割ってみました。もっと節約できるでしょうか。
import math def isprime(n): if n < 2: return False for i in range(2, int(math.sqrt(n)) + 1): if n % i == 0: return False return True
いろいろ改良ができそうです。例えば 2 を除けば偶数で割ってみる必要はないので,計算量は半分にできます。
import math def isprime(n): if n < 2: return False if n == 2: return True if n % 2 == 0: return False for i in range(3, int(math.sqrt(n)) + 1, 2): if n % i == 0: return False return True
今日(例えば 20190823)は素数か?
import datetime n = int(f"{datetime.datetime.now():%Y%m%d}") isprime(n)
math.sqrt()
は平方数については正確な平方根を与えるはずですが,浮動小数点数の精度を超える整数の場合は心配です。整数の平方根を整数の範囲で求める次の isqrt()
を使えば万全です:
def isqrt(n): if n == 0: return 0 x, y = n, (n + 1) // 2 while y < x: x, y = y, (y + n // y) // 2 return x
これを使った関数:
def isprime(n): if n < 2: return False for i in range(2, isqrt(n)+1): if n % i == 0: return False return True
もっと大きい数の素因数分解をするには,SymPy の数論ライブラリが便利です。
from sympy import factorint, isprime factorint(5040)
{2: 4, 3: 2, 5: 1, 7: 1}
factorint(20190823)
{20190823: 1}
isprime(20190823)
True
問:2020年の大晦日と2021年の元日はともに素数です。3000年までにこのような年はどれくらいあるでしょうか。