選択肢式のテストで同じ答えが連続する確率

選択肢式のテストで同じ回答が何個も続いたとき、「これは怪しい、自分間違ってるんじゃないか」と思ってしまう、というのを経験したことがある人は多いんじゃないでしょうか。


同じ答えが続くことがどのくらいの確率で起こるかはちょっとプログラムを書いたら簡単に計算できるので、やってみました。
4択で100問のテストについての結果です。

同じ答えが連続する長さの最大値がちょうどiである確率
  1: 0.0000000000
  2: 0.0051914968
  3: 0.2991464221
  4: 0.4469730949
  5: 0.1809903269
  6: 0.0505544773
  7: 0.0128794318
  8: 0.0032085392
  9: 0.0007949317
 10: 0.0001966696
 11: 0.0000486359
 12: 0.0000120251
 13: 0.0000029728
 14: 0.0000007348
 15: 0.0000001816
 16: 0.0000000449
 17: 0.0000000111
 18: 0.0000000027
 19: 0.0000000007
 20: 0.0000000002

同じ答えが連続する長さの最大値がi以上である確率
  1: 1.0000000000
  2: 1.0000000000
  3: 0.9948085032
  4: 0.6956620811
  5: 0.2486889862
  6: 0.0676986593
  7: 0.0171441821
  8: 0.0042647503
  9: 0.0010562111
 10: 0.0002612794
 11: 0.0000646098
 12: 0.0000159739
 13: 0.0000039488
 14: 0.0000009760
 15: 0.0000002412
 16: 0.0000000596
 17: 0.0000000147
 18: 0.0000000036
 19: 0.0000000009
 20: 0.0000000002


これを見ると、いちばん可能性が高いのが4連続で、5連続以上が起こる確率が1/4。
6連続以上でも7%弱だからそこまで稀なことではない、となりました。


コードは次の通り(Java)。

public class Main {

    public static void main(String[] args) throws Exception {
        final int N = 100;
        final int selection = 4;
        double[][][] p = new double[N][N + 1][N + 1]; // p[i][j][k] = i番目の問題までで、現在j個同じ答えが連続してて、
                                                      //              これまで同じ答えが連続した最大の長さがk となる確率
        p[0][1][1] = 1;
        for (int i = 1; i < N; ++i) {
            for (int j = 1; j <= i; ++j) {
                for (int k = j; k <= i; ++k) {
                    p[i][1][k] += p[i - 1][j][k] * (selection - 1) / selection;
                    if (k == j) {
                        p[i][j + 1][k + 1] += p[i - 1][j][k] / selection;
                    } else {
                        p[i][j + 1][k] += p[i - 1][j][k] / selection;
                    }
                }
            }
        }
        double[] ans = new double[N + 1];
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= N; ++j) {
                ans[i] += p[N - 1][j][i];
            }
        }
        System.out.println("同じ答えが連続する長さの最大値がちょうどiである確率");
        for (int i = 1; i <= 20; ++i) {
            System.out.printf("%3d: %.10f\n", i, ans[i]);
        }
        System.out.println();
        System.out.println("同じ答えが連続する長さの最大値がi以上である確率");
        double sum = 0;
        for (int i = 1; i <= 20; ++i) {
            System.out.printf("%3d: %.10f\n", i, 1 - sum);
            sum += ans[i];
        }
    }
}