要約
- Python でカプレカ数 (Kaprekar number) を計算してみた
- Google Colaboratory を使ったけど, その予測精度にびっくりした
はじめに
雑誌の記事でカプレカ数のことを知り, Python の習作としてプログラムを作成しました.
手元の PC に Python の環境がなかったので Google Colaboratory を使いましたが, コードの予測 (先読み) 精度が高くて驚いたので, そのことにも触れながら説明します.
なお, 末尾に Google Colaboratory のノートブックへのリンクを貼っているので, コード全体はそちらを参照してください.
カプレカ数を求めるコード
前提として, 4 桁の整数でカブレカ数を求めます.
カプレカ操作
まず定義通り, 4 桁の整数の各数字を大きい順 & 小さい順に並べます. 大きい順に並べるコードは以下の通りで, 整数を文字列に変換してからソートして, 結合させた後に整数に戻してます. 工夫点は, 4 桁未満の数字が来ても動作するように, f 文字列で書式設定をしている点です.
def descending_order(num):
return int("".join(sorted(f'{num:04d}', reverse=True)))
このコードですが, 関数名と引数を入力した時点で Google Colab が予測したコードは次の通りで, 違いは整数を文字列に変換するところだけ. 「4 桁の整数」などの前提条件が無ければ, これはこれで正解のコードでした.
def descending_order(num):
return int("".join(sorted(str(num), reverse=True)))
次に, 小さい順に並べるコードは以下の通りです. 並び方を指定するオプションを外しただけです.
def ascending_order(num):
return int("".join(sorted(f'{num:04d}')))
そして差を求めるコードです. これも, 関数名を入力した時点でコード全体を予測してくれました. びっくり.
def diff_num(num):
return descending_order(num) - ascending_order(num)
4 桁の整数で収束するまでに回数を求める
関数が準備できたので, 次に, 4 桁の整数がカプレカ数に収束するまで, カプレカ操作を繰り返すコードです. x
と y
の 2 つのリストを用意して, 4 桁の整数を x
に, 収束するまでの回数を y
に入れます.
x = []
y = []
for i in range(1000, 10000):
count = 0
prev = i
while True:
num = diff_num(prev)
if num==prev:
break
prev = num
count += 1
x.append(i)
y.append(count)
カプレカ数を求める
最後にカプレカ数を求めます. リスト y
から要素が 0 のインデックスを探し, そのインデックスに該当する要素を x
から探します. 方法はこちらを参考に, enumerate()
と内包表記を使って求めます.
candidate = [i for i, x in enumerate(y) if x == 0]
for i in candidate:
print(x[i])
6174
さいごに
Google Colaboratory (だけでなく, 世間一般の AI) のコード予測機能がすごいので, これを利用するかしないかでコードの生産性が大きく変わるなと感じた次第です. 一方で普通の検索では
- 検索でヒットする情報が似かよっている
- 世の中の進歩が速いので, その情報が作成された時期が新しくても, 載っている情報が古い場合がある
など, 目的の情報を得るのに時間がかかる場合があるので, こういうツール類は適材適所で活用していく必要があると思いました.
カプレカ数については, 4 桁の整数の場合は最大 7 回のカプレカ操作によりカプレカ数 (6147) に収束するのが分かり, その点が興味深かったです. Google Colab 上のコードでは, 横軸に 4 桁の整数, 縦軸に収束するまでの回数をプロットしたグラフを載せてますので, 興味があればご確認ください.
追伸
4 桁の数字がゾロ目のとき (たとえば 1111) の処理を無視していることに気付きました. ゾロ目のときは,
- 1 回目の操作 ;
1111 - 1111 = 0
- 2 回目の操作 ;
0 - 0 = 0
→ 1 回目と同じなので収束
という動きをしています.