【確率シミュレータ】応用情報技術者試験 午前 ランダムマークの合格率計算

🍀概要

 情報処理技術者試験の中でも人気の高い「応用情報技術者試験」午前問題。全80問が4択形式で出題され、合格ラインは48問以上の正解とされています。しかし、もし一切知識がない状態でランダムにマークした場合、どれほどの確率で合格できるのでしょうか?
 本記事では、この疑問に答えるため、モンテカルロシミュレーションを用いた確率シミュレーターを作成し、その詳細な結果とプログラムコードを公開します。
 ※本記事の執筆者は、中学校・高等学校教諭一種免許状(数学)を保有しており、数学的な観点から試験制度を分析しています。

🧾出題形式の基本

📘モンテカルロシミュレーションとは?:実践的な確率計算アプローチ

 応用情報技術者試験の午前問題で、48問以上の正解を得る確率を、厳密に数学的に計算するのは非常に複雑です。そこで登場するのが「モンテカルロシミュレーション」です。
 これは、実際にランダムにマークシートを塗りつぶし、採点する試行を莫大な回数(例えば10万回)繰り返すことで、確率を近似的に求める手法です。
 例えば、たった1回試行しただけでは、偶然の偏りが大きく、その結果は信頼できません。しかし、これを10万回、100万回と繰り返すことで、試行回数中に「合格基準に達した回数」を数え、「合格回数 ÷ 総試行回数 × 100%」と計算すれば、非常に高い精度で合格確率を推定できます。
 まさに、この「サイコロを振るように何度も試行を重ねて、事象の発生確率を導き出す」のがモンテカルロシミュレーションの核心です。この考え方に基づいて、今回の確率計算を行います。

📗さらにリアルなシミュレーションを!:受験者の実力を加味した分析

 実際の受験者が全問の答えを全く知らない、ということは稀でしょう。そこで、より現実に即したシミュレーションを行うために、以下の2つのシナリオも追加で分析しました。

  1. 「確実に得点できる問題」がある場合: 事前に一定数の問題が解けると仮定し、それ以外の問題をランダムにマークした場合の合格率を算出。
  2. 「選択肢を絞り込める学力」がある場合: 4択問題に対し、解答の精度を高める学力(例えば、誤りの選択肢を1つ除外して「3択」に絞り込める、あるいは2つ除外して「2択」にまで絞り込める)があるケースを想定し、それぞれの場合の合格率をシミュレーション。

 これらの詳細なシミュレーション結果から、あなたの学習戦略を考える上での新たな視点が見つかるかもしれません。

💻プログラム

📝ソース ※中身知りたい人向け。コピペで使えます。

プログラムコード(Java)
AppliedInformationTechnologistSimulator.java
--------------------------------------------------------------------------------------------
import java.util.Random;

/**
 * 応用情報技術者試験 午前問題の合格確率をモンテカルロシミュレーションで計算するシミュレーター。
 * 解答方式(4択、3択、2択)に応じて合格率を算出します。
 */
public class AppliedInformationTechnologistSimulator {

    // 応用情報技術者試験 午前問題の定数
    private static final int TOTAL_QUESTIONS = 80; // 総問題数
    private static final int PASSING_SCORE = 48;   // 合格点(正解数)
    private static final int DEFAULT_TRIALS = 100000; // 各シナリオでのデフォルト試行回数

    /**
     * 解答方式を定義する列挙型。
     * 各方式の正答率を保持します。
     */
    public enum AnswerMethod {
        FOUR_CHOICES("4択問題", 4),
        THREE_CHOICES("3択問題 (1つ除外)", 3),
        TWO_CHOICES("2択問題 (2つ除外)", 2);

        private final String name;
        private final int totalChoices; // 選択肢の数

        AnswerMethod(String name, int totalChoices) {
            this.name = name;
            this.totalChoices = totalChoices;
        }

        public String getName() {
            return name;
        }

        public int getTotalChoices() {
            return totalChoices;
        }
    }

    /**
     * シミュレーション結果を保持するレコード。
     * (Java 16 以降で利用可能なレコード型を使用しています。古いJavaバージョンの場合は通常のクラスに変換してください)
     */
    public record SimulationResult(int knownCorrectQuestions, double successRate) {}

    private final Random random;

    /**
     * AppliedInformationTechnologistSimulator の新しいインスタンスを生成します。
     */
    public AppliedInformationTechnologistSimulator() {
        this.random = new Random();
    }

    /**
     * 指定されたシナリオでモンテカルロシミュレーションを実行し、合格確率を計算します。
     *
     * @param answerMethod            シミュレーション対象の解答方式
     * @param knownCorrectQuestions   事前に知っている正解数
     * @param trials                  試行回数
     * @return シミュレーション結果を表す {@code SimulationResult} オブジェクト
     * @throws IllegalArgumentException 不正な引数が指定された場合
     */
    public SimulationResult simulateScenario(AnswerMethod answerMethod, int knownCorrectQuestions, int trials) {
        if (knownCorrectQuestions < 0 || knownCorrectQuestions > TOTAL_QUESTIONS) {
            throw new IllegalArgumentException(
                "事前に知っている正解数 (" + knownCorrectQuestions + ") は、0から総問題数 (" + TOTAL_QUESTIONS + ") の範囲で指定してください。"
            );
        }
        if (trials <= 0) {
            throw new IllegalArgumentException("試行回数は1以上を指定してください。");
        }

        int successfulTrials = 0;

        // 知っている問題以外の解答に必要な問題数と正解数
        int remainingQuestions = TOTAL_QUESTIONS - knownCorrectQuestions;
        int requiredCorrectForPassing = PASSING_SCORE - knownCorrectQuestions;

        // 事前知識だけで合否が確定する場合の早期リターン
        if (requiredCorrectForPassing <= 0) {
            return new SimulationResult(knownCorrectQuestions, 100.00); // 確実に合格
        }
        if (requiredCorrectForPassing > remainingQuestions) {
            return new SimulationResult(knownCorrectQuestions, 0.00); // 合格不可能
        }

        for (int i = 0; i < trials; i++) {
            int guessedCorrect = 0;
            for (int j = 0; j < remainingQuestions; j++) {
                // 解答方式に応じた確率で正解をシミュレート
                if (random.nextInt(answerMethod.getTotalChoices()) == 0) { // 例: 4択なら 0,1,2,3 のうち 0 が正解
                    guessedCorrect++;
                }
            }
            if (guessedCorrect >= requiredCorrectForPassing) {
                successfulTrials++;
            }
        }

        double successRate = (double) successfulTrials / trials * 100;
        return new SimulationResult(knownCorrectQuestions, successRate);
    }

    /**
     * シミュレーション結果を表示します。
     *
     * @param result 表示するシミュレーション結果
     */
    public void displayResult(SimulationResult result) {
        System.out.printf("・事前に%d問知っている場合: 合格率: %.2f%%\n", result.knownCorrectQuestions(), result.successRate());
    }

    /**
     * メインメソッド。応用情報技術者試験の各種シナリオでシミュレーションを実行します。
     */
    public static void main(String[] args) {
        AppliedInformationTechnologistSimulator simulator = new AppliedInformationTechnologistSimulator();

        System.out.println("★応用情報技術者 午前問題 突破確率計算:ランダム選択方式(モンテカルロシミュレーション)★");
        System.out.println("---");
        System.out.println("総問題数: " + TOTAL_QUESTIONS + "問, 合格に必要な正解数: " + PASSING_SCORE + "問");
        System.out.println("---");
        System.out.println();

        // 4択問題のシミュレーション
        System.out.println("■" + AnswerMethod.FOUR_CHOICES.getName() + " 試行結果");
        for (int i = 0; i <= PASSING_SCORE; i++) {
            try {
                SimulationResult result = simulator.simulateScenario(AnswerMethod.FOUR_CHOICES, i, DEFAULT_TRIALS);
                simulator.displayResult(result);
            } catch (IllegalArgumentException e) {
                System.err.println("エラー: " + e.getMessage());
            }
        }
        System.out.println();

        // 3択問題のシミュレーション (1つ選択肢を除外できる場合)
        System.out.println("■" + AnswerMethod.THREE_CHOICES.getName() + " 試行結果");
        for (int i = 0; i <= PASSING_SCORE; i++) {
            try {
                SimulationResult result = simulator.simulateScenario(AnswerMethod.THREE_CHOICES, i, DEFAULT_TRIALS);
                simulator.displayResult(result);
            } catch (IllegalArgumentException e) {
                System.err.println("エラー: " + e.getMessage());
            }
        }
        System.out.println();

        // 2択問題のシミュレーション (2つ選択肢を除外できる場合)
        System.out.println("■" + AnswerMethod.TWO_CHOICES.getName() + " 試行結果");
        for (int i = 0; i <= PASSING_SCORE; i++) {
            try {
                SimulationResult result = simulator.simulateScenario(AnswerMethod.TWO_CHOICES, i, DEFAULT_TRIALS);
                simulator.displayResult(result);
            } catch (IllegalArgumentException e) {
                System.err.println("エラー: " + e.getMessage());
            }
        }
        System.out.println("---");
    }
}

▶️WEB実行環境

glot.ioというWEB上でプログラムを実行できる環境があったため、誰でも動作確認ができるようにリンクを掲載しました。以下から実行(Run)できます。
https://glot.io/snippets/h9hezkwzc1

🧭実行結果

各10万回試行した、実行結果ログ ※長いので、折りたたみます。
★応用情報技術者 午前問題 突破確率計算:ランダム選択方式(モンテカルロシミュレーション)★
---
総問題数: 80問, 合格に必要な正解数: 48問
---

■4択問題 試行結果
・事前に0問知っている場合: 合格率: 0.00%
・事前に1問知っている場合: 合格率: 0.00%
・事前に2問知っている場合: 合格率: 0.00%
・事前に3問知っている場合: 合格率: 0.00%
・事前に4問知っている場合: 合格率: 0.00%
・事前に5問知っている場合: 合格率: 0.00%
・事前に6問知っている場合: 合格率: 0.00%
・事前に7問知っている場合: 合格率: 0.00%
・事前に8問知っている場合: 合格率: 0.00%
・事前に9問知っている場合: 合格率: 0.00%
・事前に10問知っている場合: 合格率: 0.00%
・事前に11問知っている場合: 合格率: 0.00%
・事前に12問知っている場合: 合格率: 0.00%
・事前に13問知っている場合: 合格率: 0.00%
・事前に14問知っている場合: 合格率: 0.00%
・事前に15問知っている場合: 合格率: 0.00%
・事前に16問知っている場合: 合格率: 0.00%
・事前に17問知っている場合: 合格率: 0.00%
・事前に18問知っている場合: 合格率: 0.01%
・事前に19問知っている場合: 合格率: 0.01%
・事前に20問知っている場合: 合格率: 0.03%
・事前に21問知っている場合: 合格率: 0.04%
・事前に22問知っている場合: 合格率: 0.08%
・事前に23問知っている場合: 合格率: 0.15%
・事前に24問知っている場合: 合格率: 0.28%
・事前に25問知っている場合: 合格率: 0.49%
・事前に26問知っている場合: 合格率: 0.85%
・事前に27問知っている場合: 合格率: 1.31%
・事前に28問知っている場合: 合格率: 2.18%
・事前に29問知っている場合: 合格率: 3.45%
・事前に30問知っている場合: 合格率: 5.56%
・事前に31問知っている場合: 合格率: 8.38%
・事前に32問知っている場合: 合格率: 12.49%
・事前に33問知っている場合: 合格率: 17.51%
・事前に34問知っている場合: 合格率: 24.43%
・事前に35問知っている場合: 合格率: 32.53%
・事前に36問知っている場合: 合格率: 41.85%
・事前に37問知っている場合: 合格率: 52.17%
・事前に38問知っている場合: 合格率: 62.90%
・事前に39問知っている場合: 合格率: 72.95%
・事前に40問知っている場合: 合格率: 81.95%
・事前に41問知っている場合: 合格率: 88.84%
・事前に42問知っている場合: 合格率: 94.07%
・事前に43問知っている場合: 合格率: 97.21%
・事前に44問知っている場合: 合格率: 98.86%
・事前に45問知っている場合: 合格率: 99.67%
・事前に46問知っている場合: 合格率: 99.93%
・事前に47問知っている場合: 合格率: 100.00%
・事前に48問知っている場合: 合格率: 100.00%

■3択問題 (1つ除外) 試行結果
・事前に0問知っている場合: 合格率: 0.00%
・事前に1問知っている場合: 合格率: 0.00%
・事前に2問知っている場合: 合格率: 0.00%
・事前に3問知っている場合: 合格率: 0.00%
・事前に4問知っている場合: 合格率: 0.00%
・事前に5問知っている場合: 合格率: 0.00%
・事前に6問知っている場合: 合格率: 0.01%
・事前に7問知っている場合: 合格率: 0.00%
・事前に8問知っている場合: 合格率: 0.00%
・事前に9問知っている場合: 合格率: 0.02%
・事前に10問知っている場合: 合格率: 0.02%
・事前に11問知っている場合: 合格率: 0.04%
・事前に12問知っている場合: 合格率: 0.07%
・事前に13問知っている場合: 合格率: 0.13%
・事前に14問知っている場合: 合格率: 0.16%
・事前に15問知っている場合: 合格率: 0.28%
・事前に16問知っている場合: 合格率: 0.43%
・事前に17問知っている場合: 合格率: 0.65%
・事前に18問知っている場合: 合格率: 1.03%
・事前に19問知っている場合: 合格率: 1.56%
・事前に20問知っている場合: 合格率: 2.20%
・事前に21問知っている場合: 合格率: 3.17%
・事前に22問知っている場合: 合格率: 4.48%
・事前に23問知っている場合: 合格率: 6.34%
・事前に24問知っている場合: 合格率: 8.87%
・事前に25問知っている場合: 合格率: 11.75%
・事前に26問知っている場合: 合格率: 15.41%
・事前に27問知っている場合: 合格率: 20.34%
・事前に28問知っている場合: 合格率: 25.97%
・事前に29問知っている場合: 合格率: 32.48%
・事前に30問知っている場合: 合格率: 39.44%
・事前に31問知っている場合: 合格率: 47.05%
・事前に32問知っている場合: 合格率: 55.30%
・事前に33問知っている場合: 合格率: 63.35%
・事前に34問知っている場合: 合格率: 71.57%
・事前に35問知っている場合: 合格率: 78.52%
・事前に36問知っている場合: 合格率: 84.33%
・事前に37問知っている場合: 合格率: 89.45%
・事前に38問知っている場合: 合格率: 93.37%
・事前に39問知っている場合: 合格率: 96.18%
・事前に40問知っている場合: 合格率: 97.93%
・事前に41問知っている場合: 合格率: 98.99%
・事前に42問知っている場合: 合格率: 99.58%
・事前に43問知っている場合: 合格率: 99.83%
・事前に44問知っている場合: 合格率: 99.96%
・事前に45問知っている場合: 合格率: 99.99%
・事前に46問知っている場合: 合格率: 100.00%
・事前に47問知っている場合: 合格率: 100.00%
・事前に48問知っている場合: 合格率: 100.00%

■2択問題 (2つ除外) 試行結果
・事前に0問知っている場合: 合格率: 4.74%
・事前に1問知っている場合: 合格率: 5.78%
・事前に2問知っている場合: 合格率: 7.02%
・事前に3問知っている場合: 合格率: 8.64%
・事前に4問知っている場合: 合格率: 10.52%
・事前に5問知っている場合: 合格率: 12.58%
・事前に6問知っている場合: 合格率: 14.68%
・事前に7問知っている場合: 合格率: 17.47%
・事前に8問知っている場合: 合格率: 20.58%
・事前に9問知っている場合: 合格率: 23.87%
・事前に10問知っている場合: 合格率: 27.74%
・事前に11問知っている場合: 合格率: 31.24%
・事前に12問知っている場合: 合格率: 35.87%
・事前に13問知っている場合: 合格率: 40.54%
・事前に14問知っている場合: 合格率: 45.07%
・事前に15問知っている場合: 合格率: 50.21%
・事前に16問知っている場合: 合格率: 54.98%
・事前に17問知っている場合: 合格率: 59.82%
・事前に18問知っている場合: 合格率: 64.72%
・事前に19問知っている場合: 合格率: 69.64%
・事前に20問知っている場合: 合格率: 73.96%
・事前に21問知っている場合: 合格率: 77.95%
・事前に22問知っている場合: 合格率: 82.04%
・事前に23問知っている場合: 合格率: 85.49%
・事前に24問知っている場合: 合格率: 88.51%
・事前に25問知っている場合: 合格率: 91.35%
・事前に26問知っている場合: 合格率: 93.35%
・事前に27問知っている場合: 合格率: 95.08%
・事前に28問知っている場合: 合格率: 96.56%
・事前に29問知っている場合: 合格率: 97.55%
・事前に30問知っている場合: 合格率: 98.34%
・事前に31問知っている場合: 合格率: 98.97%
・事前に32問知っている場合: 合格率: 99.30%
・事前に33問知っている場合: 合格率: 99.59%
・事前に34問知っている場合: 合格率: 99.79%
・事前に35問知っている場合: 合格率: 99.86%
・事前に36問知っている場合: 合格率: 99.94%
・事前に37問知っている場合: 合格率: 99.98%
・事前に38問知っている場合: 合格率: 99.99%
・事前に39問知っている場合: 合格率: 99.99%
・事前に40問知っている場合: 合格率: 99.99%
・事前に41問知っている場合: 合格率: 100.00%
・事前に42問知っている場合: 合格率: 100.00%
・事前に43問知っている場合: 合格率: 100.00%
・事前に44問知っている場合: 合格率: 100.00%
・事前に45問知っている場合: 合格率: 100.00%
・事前に46問知っている場合: 合格率: 100.00%
・事前に47問知っている場合: 合格率: 100.00%
・事前に48問知っている場合: 合格率: 100.00%
---

いかがでしたでしょうか。

今回のシミュレーション結果で特に注目すべきは、解答の絞り込み能力が合否に与える大きな影響です。

🌧️厳しい現実:完全ランダムと4択絞り込み不可の場合

「4択の絞り込みができないレベル」(赤線部分)においては、事前に30問の答えを知っていても、合格率は5%程度という厳しい結果になりました。これは驚くべき数字であり、単に問題数をこなすだけでなく、選択肢を減らす能力がいかに重要であるかを物語っています。さらに、完全にランダムにマークした場合は、合格率が0%という結果は、運任せでは合格が極めて難しい現実を浮き彫りにしています。

合格率を90%以上に引き上げるためには、4択絞り込み不可のレベルだと、事前に42問以上の正解を知っている必要があるようです。これは総問題数80問中、半分以上を確実に正解できる実力が必要であることを示しています。

☀️希望の光:2択まで絞り込める場合

一方で、「2択の絞り込みまでできるレベル」(緑線部分)では、希望が見えます。このレベルでは、事前に25問の答えを知っていれば、合格率を90%以上に高めることができるという結果が出ました。

このことから、たとえ全問を完璧に解答できなくても、不正解の選択肢を確実に絞り込む努力が、合格への大きな鍵となることがわかります。諦めずに知識を深め、選択肢を減らす力を養うことが、合格への道を大きく開くでしょう。

今回のシミュレーションが、あなたの学習戦略を練る上での一助となれば幸いです。