菊池律です。

三日坊主にならないように、三日毎に書きます。

numpyを使って競プロの考察を簡単にできないかなあと考えました。

numpyを使って考察を簡単にしたいなあという次第です。
ABC101のD問題Snuke Numbersを使って云々したいと思います。
↓問題
atcoder.jp

とりあえず、すぬけ数の定義を理解するのが難しいです。
簡単に言うと、nより大きい任意の数字mについて、{\frac{x}{S(x)}}をした時、{\frac{n}{S(n)}}より小さい値が存在しないということです。
手を動かして実験をしてみるというのが一番簡単なのですがもうちょっと簡単かつグラフなどで可視化できないかなあという感じです。

import numpy as np
import matplotlib.pyplot as plt

test = 500
x = np.arange(1, test + 1)
y = np.array([num/sum(map(int, str(num))) for num in x])

# すぬけ数のインデックスを見つける
sunuke_indices = []
for i in range(len(y)):
    min_num = min(y[i:])
    if y[i] == min_num:
        sunuke_indices.append(i)

# グラフを描画
plt.figure(figsize=(10, 6))
plt.plot(x, y, label=r'$\frac{x}{\sum \, \mathrm{digits \, of} \, x}$')
plt.scatter(x[sunuke_indices], y[sunuke_indices], color='red', label='Sunuke Numbers')
plt.xlabel('x')
plt.ylabel(r'$\frac{x}{\sum \, \mathrm{digits \, of} \, x}$')
plt.title('Plot of Sunuke Numbers')
plt.legend()
plt.grid(True)
plt.show()

実行したやつ

適当に書いてみました。500までの数字でしか比較してませんが、以下のことが分かると思います。
・100の倍数の時、{\frac{x}{S(x)}}がめちゃくちゃでかくなっている
・上とは逆に、...99みたいな数字の時{\frac{x}{S(x)}}は小さくなっている
直感的ですが、{\frac{x}{y}}をなるべく小さくするには、yを最大化させxをなるべく小さくすればいいと考えられます。したがって、{\frac{x}{S(x)}}についても、S(x)を最大化させるにはとにかく9が多い方が良いんじゃないかなとなります。
この考察は、numpyとmatplotlibを使ってすぬけ数を可視化したおかげに違いないです。 でも本当は単純にコードを書いて直接すぬけ数を求めるのが楽かもしれない...。 参考までに、100000までの数字のすぬけ数を求めたいと思います。

test=10**5
x=list(i for i in range(1,test+1))
y=list(num/sum(list(map(int,list(str(num))))) for num in x)
for i in range(len(y)):
    min_num=min(y[i:])
    if y[i]==min_num:
        print(x[i])
1
2
3
4
5
6
7
8
9
19
29
39
49
59
69
79
89
99
199
299
399
499
599
699
799
899
999
1099
1199
1299
1399
1499
1599
1699
1799
1899
1999
2999
3999
4999
5999
6999
7999
8999
9999
10999
11999
12999
13999
14999
15999
16999
17999
18999
19999
20999
21999
22999
23999
...
...
100000

ということで、numpyライブラリなどを使って複雑なコードを書いておしゃれに考察をしようとするよりシンプルに考察をした方がいいという結論になりました。
僕はまだ上記の問題を解けていないのでもうちょっと頑張ります。皆さんも頑張ってください。 まとめ よく見たら今回の考察にnumpyはいらないですね。