Cou氏の徒然日記

ほのぼの日記ブログです。

数学の問題

年末特番で「IQヴィーナス」という、女子高生の知識ナンバー1を競う番組がやっていたので見たんですが、高校生クイズとは違って、出題される問題は、結構答えられそうな難易度の問題だったこともあって、見ていて面白かったですね。
ただ、分からない問題はさっぱり分かりませんが(苦笑)

そんな中、決勝の数学の問題では…
「3の倍数ではなく、かつ3を含まない、1以上10000以下の数はいくつあるか?」
という問題がありました。
昔なら自力で解こうと思ったんでしょうが、今はもうプログラムですぐに求められるだろ…と思っちゃっうようになってしまい、解く気力がなかったり…。
ただ、数学的な解き方を見るとなるほど~と思っちゃうんですよね。

ちょっと検算のために、プログラムで結果を見てみましたが…


private void outputCountOfNumbers() {
    int cnt = 0;
    for (int number = MIN_OF_NUMBER; number <= MAX_OF_NUMBER; number++) {
        if (number % 3 == 0) {
            // 3の倍数は除外
            continue;
        }
        else if (Integer.toString(number).contains("3"))
        {
            // 3を含む場合は除外
            continue;
        }
        // 3の倍数でない かつ 3を含まない場合,総数をカウントアップ
        cnt++;
    }
    // 3の倍数でない かつ 3を含まない という条件を満たす数の総数を出力
    System.out.println(cnt);               
}
// 最大値
private int MAX_OF_NUMBER= 10000;
// 最小値
private int MIN_OF_NUMBER= 1;



これを実行してみると、確かに「4375」

う~ん、数学の理論ってすごいなぁ…と思った一問でした。
実際、その解き方をプログラミングするのは難しいでしょうし…。
今のご時世、これくらいの数値なら総当たりでもあっという間にプログラム演算も終わりますので、理論を考えるのと、プログラムで解決するのと…どちらで対応していくのが正しいのか悩ましくなってしまいます。

…と言っても、やはり理論で考えないと、こういった総当たりのテストをすることになってしまいますので、当然、理論からよいアルゴリズムを考えないと、いいものはできあがらないですし、大きな数値だと全然計算に時間がかかってしまいます。

実際、上記のアルゴリズムの場合,MAX_OF_NUMBERが「10,000」だから一瞬で終わりますが、「100,000,000」だと数秒かかってしまいますからね。