ひょっとしたら限りなく100%に近づくのが正解?と思ったので、もう少し考えてみることに。
アホみたいに1つづつ数を調べていると手持ちのCPUパワーだと100億ぐらいが限界そうなので、 下記のようなアホになる数の近似値を求める関数を考えてみました。
#!/usr/bin/ruby
# 問題を簡単にするため、このプログラムではp = log10(n)というpを定義し、
# pが1以上の整数の場合のみ調べています。
# 要するに、n=10,100,1000,...というケースのみ調べています。
# 0〜(10**p)-1までの間に3を含む数がいくつあるかを返す関数
def h3(p)
return 0 if p == 0
return 1 if p == 1
# (0~29, 40〜99のような普通ゾーン) + (30〜39のような3が連続するゾーン)
h3(p-1) * 9 + 10 ** (p - 1)
end
# 0〜(10**p)-1までの間で何回アホになるかを返す関数
def calc_aho(p)
n = 10 ** p
# (3の倍数) + (3を含む数) - (3の倍数でかつ3を含む数)
# n / 3 + h3(p) - (h3(p) / 3)
(n + 2 * h3(p)) / 3
end
puts "n,aho_count,aho_percent"
# 10**1〜10**100までのケースについて調べてみる
(1..100).each {|p|
n = 10**p
aho_count = calc_aho(p)
aho_percent = aho_count / n.to_f * 100
puts "#{n},#{aho_count},#{aho_percent}"
}
前に求めた結果とこの関数の結果を比較すると、かなりいい感じに近似値を求めることができていると思われます。
| n | 力づくで数えたアホになる数の総数 | 上記プログラムを使って求めた近似値 |
| 10 | 3 | 4 |
| 100 | 45 | 46 |
| 1000 | 513 | 514 |
| 10000 | 5625 | 5626 |
| 100000 | 60633 | 60634 |
| 1000000 | 645705 | 645706 |
| 10000000 | 6811353 | 6811354 |
| 100000000 | 71302185 | 71302186 |
| 1000000000 | 741719673 | 741719674 |
| 10000000000 | 7675477065 | 7675477066 |
以下は10〜10**100までの数を求めた結果です。

まず、アホになる数の総数は下記の式を満たしていると考えられます。
アホになる数の総数 = 3の倍数の総数 + 3を含む数の総数 - 3の倍数かつ3を含む数の総数

プログラムでは、それぞれの項を次のようにして求めています。
| 3の倍数の総数 | nが与えられたとき、単純にn/3としています。 |
| 3を含む数の総数 | 再帰を使って求めています。求め方はプログラムの方を参照してください |
| 3の倍数かつ3を含む数の総数 | 3を含む数の総数の1/3と仮定しています。 |
3を含む数の中には1/3ぐらい3の倍数が含まれているだろうとかなり適当に仮定しているのですが、 適当な割にはなぜか100億ぐらいまで結果とほぼ一致していてかなり不思議な感じがします。
この式がどこまで正確にアホになる数を求めることができるのか、時間があればさらに追求してみたいと思いますw
ナベアツ問題、別アプローチ?でやってみました。<br>http://d.hatena.ne.jp/comiken/20080428#p8<br>批評お願いします〜。
お久しぶりです。おもしろいっすね。<br><br>n桁の整数が3を含む確率は 1-0.9^n <br>n->∞のとき、1に収束するので100%アホになるってのはどうっすか?<br><br>3の倍数の確率1/3を絡めてないんで、いまいちだなぁ・・・