出典: Project Euler(日本語 翻訳サイト)
ProjectEuler.net(英語サイト)
Problem 45
三角数, 五角数, 六角数は以下のように生成される.
三角数 | Tn=n(n+1)/2 | 1, 3, 6, 10, 15, ... |
五角数 | Pn=n(3n-1)/2 | 1, 5, 12, 22, 35, ... |
六角数 | Hn=n(2n-1) | 1, 6, 15, 28, 45, ... |
次の三角数かつ五角数かつ六角数な数を求めよ.
-----
私の解答例は以下です。畳んでいます。
import math def h(n): return not (-1+math.sqrt(1+n*8))%2 def g(n): return not (1+math.sqrt(1+n*24))%6 def f(n): i = 0 while True: i += 1 s = i*(2*i-1) if s<=n: continue if g(s) and h(s): return s print f(40755)
六角数の進み方が一番早いので、六角数を1つずつ計算してそれが五角数、三角数であるか判定する方法でやります。
3つの関数を使っています。
1.関数h(n)
・return not (-1+math.sqrt(1+n*8))%2
三角数の判定です。
定義式から、x(x+1)/2 = nを満たす整数xが存在すればnは三角数です。
xの二次方程式として、二次方程式の解の公式より、
x = -1±√(1+8n)/2
%演算子は割り算の余りです。
整数xが存在すれば上記の余りがない(論理的にFalse)です。
このxが整数かどうかは、+か-のどちらで判定しても同じなので、
ここでは+の方を採用しています。
2.関数g(n)
・五角数の判定です。problem44と同じです。
3.関数f(n)
・nを超える最小の三角数かつ五角数かつ六角数である数を返します。
・i = 0
初期値としてnを設定します。
・while True:
無限ループです。
・i += 1
iは1ずつ増えるカウンターです。
・s = i*(2*i-1)
sはi番目の六角数です。
・if s<=n: continue
六角数sがn以下の場合は次の六角数に進みます。
・if g(s) and h(s): return s
六角数sが五角数かつ三角数の場合、その数sを返します。
3.関数の外
・print f(40755)
問題に従い、40755を超える範囲で関数f(n)を呼び出します。
解答はこのすぐ下の行です。文字の色を白にしてます。選択状態にすると見えます。
1533776805
0 件のコメント:
コメントを投稿