ある整数xは2のn乗であるか?正しく判定できるコードを書いてみろ!
xが2のn乗である場合には"OK"を出力して、そうではない場合は"NG"を出力する。
こんな問題を解く時に、一番簡単な書き方はどうするか?
以前、似たような問題を解いたのは以下のコード。
x = 256
while x != 1:
x /= 2
if x == 1:
print("OK")
break
if x % 2 != 0:
print("NG")
break
# 出力結果 OK
我ながらダサいコードを書いておりました。
一応、通るので当時はとりあえずOK!って感じで終わらせたような気がします。
今回、書き直したコード。
x = 256
print("OK" if x & (x - 1) == 0 else "NG")
# 出力結果 OK
うん。今回の書き方でグッとスマートになりました。
でも、なぜ、この書き方が機能するのか?
これは、xが2のn乗である場合、10進数を2進数に基数変換すると
必ず先頭の1のみ1で他は0になる(桁が上がった最初の数字)という性質を利用しています。
(例)
10進数 4 → 2進数 100
10進数 16 → 2進数 10,000
10進数 64 → 2進数 1,000,000
など
そして、xが2のn乗である場合、当たり前ですが x - 1 は必ず全て1になるという事になります。
この性質を利用すれば、n と n - 1 を論理積で比較して 0 になれば、xは2のn乗であるという事が証明できます。
今回勉強した事を忘れないようにメモしておこうと思い記載しました。
以上