Pythonで漸化式のn番目の項を求める方法:log₂(bₙ)の計算
次のような数列 bn を考えてみましょう。この数列は、b1 = 1 および bn+1/bn = 2n という漸化式で表されます。ここでの課題は、与えられた n に対して log2(bn) の値を求めることです。
たとえば、入力が 6 の場合、出力は 15 になります。これは log2(bn) = (n × (n − 1)) / 2 = (6 × (6 − 1)) / 2 = 15 となるためです。
数学的な導出手順
この問題は、漸化式を段階的に展開することで解くことができます。
bn+1/bn = 2n
bn/bn−1 = 2n−1
…(中略)…
b2/b1 = 21
上記の式をすべて掛け合わせると、左辺の分子・分母が打ち消し合い、次のようになります。
(bn+1/bn) · (bn/bn−1) … (b2/b1) = 2n + (n−1) + … + 1
したがって、
bn+1/b1 = 2n(n+1)/2
ここで、1 + 2 + 3 + … + (n−1) + n = n(n+1)/2 という等差数列の和の公式を使用しています。
初期値として b1 = 1 を仮定すると、
bn+1 = 2n(n+1)/2 × b1 = 2n(n+1)/2
n を (n+1) で置き換えると、最終的に次の式が得られます。
bn = 2n(n−1)/2
両辺の底を2とする対数を取ると、
log2(bn) = n(n−1)/2
Pythonでの実装例
それでは、実際の実装を見てみましょう。
def add_upto_n(n):
res = (n * (n - 1)) / 2
return res
n = 6
print(int(add_upto_n(n)))入力
6
出力
15
まとめ
このように、漸化式を直接計算する代わりに、数列の規則性を解析して閉じた形(一般項)を導出することで、O(1) の計算量で任意の n 番目の項の対数値を瞬時に求めることができます。大きな n に対しても効率的に動作するのが、このアプローチの大きな利点です。
-
Pythonでビトニックシーケンスのビトニックポイントを二分探索で効率的に求める方法
ビトニックシーケンス(Bitonic Sequence)とは、最初は厳密に増加し続け、ある一点を境にして厳密に減少していく数列のことです。この増加から減少へと切り替わる境界点のことを「ビトニックポイント」と呼びます。例えば、入力が [7, 8, 9, 12, 10, 6, 3, 2] の場合、数列は 12 まで増加し、その後減少に転じるため、出力は 12 となります。なお、単調増加のみ、または単調減少のみの数列にはビトニックポイントは存在しません。解法のアプローチビトニックポイントを線形探索で見つけると計算量は O(n) になりますが、数列の性質を利用すると二分探索によって O(log n)
-
Pythonで別のリストをインデックスにしてリストの要素を取得する3つの方法
Pythonでは、あるリストの要素を、別のリストに格納された数値(インデックス位置)に基づいて取り出したい場面がよくあります。例えば、曜日名が入ったリストから、指定された位置の要素だけを抜き出すようなケースです。本記事では、この処理を実現する3つの方法を、具体的なコード例とともに解説します。 mapと__getitem__を組み合わせる方法 リストには特殊メソッド(マジックメソッド)である__getitem__が用意されており、これを使うとリストの要素へアクセスできます。このメソッドをmap関数と組み合わせることで、2つ目のリストの各要素をインデックスとして扱い、1つ目のリストから対応する要