Pythonで桁を並べ替えて2の累乗を作れるか判定するプログラム
正の整数 N が与えられたとします。この数の桁を任意の順序に並べ替え(元の順序のままでも可)、先頭の桁が0にならないようにします。そして、その結果得られる数が2の累乗になるようにできるかどうかを判定する必要があります。
例えば、入力が N = 812 の場合、出力は True となります。これは「812」の桁を並べ替えると「128」(= 27)を作れるためです。
解法のアプローチ
この問題を解く鍵となるのは、「桁を並べ替えた数同士は、ソート後の桁の並びが必ず一致する」という性質です。つまり、ある数がNの桁を並べ替えたものであるかを調べるには、両者を文字列に変換して文字をソートし、一致するかどうかを比較すればよいのです。
具体的には、以下の手順で解くことができます。
- 変数
iを1で初期化します。 iが 1,000,000,000 以下である限り、以下を繰り返します。iを文字列に変換し、その文字をソートしたものをsとします。nを文字列に変換し、その文字をソートしたものをtとします。sとtが一致する場合、Trueを返します。iを2倍します。
- ループが終了しても一致するものが見つからなければ、
Falseを返します。
2の累乗は32ビット整数の範囲で最大でも 230 = 1,073,741,824 なので、上限を10億(1,000,000,000)とすれば、すべての候補を網羅できます。
実装例
それでは、実際のPythonコードを見て、より深く理解しましょう。
def solve(n):
i = 1
while i <= 1000000000:
s = str(i)
s = ''.join(sorted(s))
t = str(n)
t = ''.join(sorted(t))
if s == t:
return True
i = i * 2
return False
N = 812
print(solve(N))入力
812
出力
True
コードの解説
このプログラムでは、まず i = 1 から始めて、2の累乗(1, 2, 4, 8, 16, ...)を順番に生成していきます。それぞれの累乗について、その数字を文字列に変換してソートし、入力 N を同様にソートした結果と比較します。
N = 812 の場合、桁をソートすると "128" となります。一方、2の累乗を順に調べていくと、i = 128 のときのソート結果も "128" となり、両者が一致します。したがって、True が返されます。
計算量について
2の累乗の候補は高々31個(20 から 230)しかないため、各候補に対する文字列のソートと比較の処理を合わせても、全体として非常に効率的に動作します。時間計算量は O(31 × d log d)(d は桁数)程度であり、実質的にはほぼ定数時間で処理が完了すると言えます。
-
Pythonで多角形の外周(周囲長)を求めるプログラム
問題の概要2次元平面上にある単純な多角形(自己交差しないポリゴン)の頂点が、順序付きの点のリストとして与えられているとします。このとき、その多角形の外周(周囲長)を求めることが目的です。例として、入力が points = [(0, 0), (0,5), (3, 5), (3,0)] の場合を考えてみましょう。このときの出力は 16 になります。これは、図からも分かるように、長さ3の辺が2本、長さ5の辺が2本存在するためです。したがって、2×5 + 2×3 = 16 となります。アルゴリズムの考え方この問題は、「隣接する2つの頂点間の距離をすべて計算して合計する」というシンプルなアプローチで解く
-
Pythonで数値が2の累乗かどうかを判定するプログラム
本記事では、与えられた数値が2の累乗(べき乗)であるかどうかを判定する方法について、考え方と実装手順をわかりやすく解説します。 問題の定義 ある整数 n が与えられたとき、その数が2の累乗(1, 2, 4, 8, 16, …)であるかどうかを判定します。 アプローチ 判定には「繰り返し2で割る」というシンプルな方法を使います。考え方は以下の通りです。 入力された数値 n を、1になるまで繰り返し2で割っていきます(n = n // 2)。 割る過程で n % 2 の結果が0以外(奇数)になり、かつ n が1でない場合は、その数は2の累乗ではありません。 最終的に n がちょうど1になれば、そ