日本語翻訳サイトは、プロジェクトオイラー日本語 でネット検索です。
問123「素数の自乗で割った余り」
pn を n 番目の素数とする. (p1 = 2, p2 = 3, ...)
r を (pn - 1)n + (pn + 1)n を pn2 で割った余りとする.
例えば, n = 3 のとき, p3 = 5 であり, 43 + 63 = 280 ≡ 5 mod 25.
余り r が 109 より大きくなる n の最小値は 7037 である.
余り r が 1010 より大きくなる最初の n を求めよ.
注意!!!
自力で解きたい人へ
以降の記述には解法に関するネタバレが含まれます。
私の回答例は以下の通りです。
def f(rmin): for i, p in enumerate(P()): n = i + 1 if n % 2: r = (2*n*p) % (p*p) if r > rmin: return n, p, r def P(): L, i = [2], 1 yield 2 while True: i += 2 for j in L: if not i%j: break else: L.append(i) yield i if __name__=="__main__": rmin = 10**10 n, p, r = f(rmin) print "n =", n, "(素数p =", p, ", 余りr =", r, ")"
1.関数f(rmin)
・最小の余りrminを受け取り、問題に合うn番目の素数pとそのときの余りrについて、n,p,rを返します。
・この問題は問120の続きの問題です。
問120では、
(a - 1)n + (a + 1)n を n2 で割った余りをrとしていましたが、
本問では、
(pn - 1)n + (Pn + 1)n を pn2で割った余りをrとしています。
・問120の式に、a=pnを代入すると以下のことがわかります。
余りrは、nが偶数か奇数かでパターンが異なります。
nが偶数の場合、余りrはaに関わらず 2 です。
nが奇数の場合、余りrは 2npn をpn2で割った余りです。
・pは素数なので、2以外はすべて奇数です。
題意から答えは明らかに2よりも大きく、必ず奇数です。
このため、nが偶数のときは処理せず飛ばします。
2.関数P()
・素数を小さい方から昇順に返すジェネレーターです。呼び出しの都度、次の素数を返却します。
・問108で作成した関数を改良しました
解答はこのすぐ下の行です。文字の色を白にしてます。選択状態にすると見えます。
n = 21035 (素数p = 237737 , 余りr = 10001595590 )
0 件のコメント:
コメントを投稿