世界のナベアツ方程式

数学は苦手なのでこういうのがわかる人ってすごいなーと思ってしまう。

「3の倍数と3の付く数字の時だけアホになります」という男がいたとして、1から10^n(10のn乗)まで数字を数えた場合、アホになった回数Aを求める数式を一般化して示すことはできますか。

「3の倍数と3の付く数字の時だけアホになります」という男がい… - 人力検索はてな

ふつうの感覚でいうと、(ここで言う「ふつうの感覚」というのは「俺の感覚」という意味ですが) 「1 から任意の自然数 n まで」の数式を考えようとするはず。(10のn乗まで、ではなくて、「nまで」ってこと)

で、俺はボーッと読んでしまって、「そうか、すごいなあ」で終わってしまったのだが、

上記の計算式が正しければ、1〜40までの場合は

40 = 10 ^ n
  ↓
n = 1.60206

にすりゃ良いと思って計算した所、小数点が出た(゜Д゜)

sk

そうだ、対数だ。忘れてた。

(ちなみにSukima Windows Plusさんは5年ぐらい前からずーっと楽しく読み続けているとても面白いブログである)

で、Pythonで計算してみると確かに……

>>> import math; f = lambda x: 10 ** x - 9 ** x * 2 / 3 - 1;
print f(math.log(40, 10))

16.4751199293

……小数になる。

よくかんがえてみると、3の倍数と3の付く数なんだから、グラフのx軸に「読み上げる数」、y軸に「アホになる回数」の累計をプロットしてったら、グラフの線はギザギザになるはずだ。

早速、グラフを描いてみた。

赤い線が数式の線。青い線が実際に数えたアホになる回数。10と100のところでは線が交差するが、それ以外ではずれてるところが多い。30台ではどんどんずれていく。

10,000まで数えるとどうなるだろうか。

やはり3000台でかなりずれる。

質問された方の、「10のn乗だったら数式で表すことができるかもしれない」という発想が、まず、すごいと思った。

参考:

グラフを描くのに使った「10,000までのアホになる回数」のデータはこちら

それを出すのに使ったスクリプトは↓こちら。(アホみたいなスクリプトで恥ずかしいが)

import time, sys

s = time.time()

a = 0
for i in range(1, 10001):
    if i % 3 == 0 or str(i).find('3') != -1:
        a += 1
    print "%d\t%d" % (i, a)

sys.stderr.write(str(time.time() - s))