A multiple choice test has four possible answers to each of 16 questions.
A student guesses the answer to each question, so the probability
of getting a correct answer on any given question is one in four,
a quarter, 1/4, 25% or fraction 0.25. The conditions of the binomial
experiment are assumed to be met: n = 16 questions constitute the
trials; each question results in one of two possible outcomes (correct
or incorrect); the probability of being correct is 0.25 and is constant
if no knowledge about the subject is assumed; the questions are answered
independently if the student's answer to a question in no way influences
his/her answer to another question.

First, we need to be able to use the binomial distribution constructor
(and some std input/output, of course).

The number of correct answers, X, is distributed as a binomial random
variable with binomial distribution parameters: questions n and success
fraction probability p. So we construct a binomial distribution:

intquestions=16;// All the questions in the quiz.
intanswers=4;// Possible answers to each question.
doublesuccess_fraction=1./answers;// If a random guess, p = 1/4 = 0.25.
binomialquiz(questions,success_fraction);

and display the distribution parameters we used thus:

cout<<"In a quiz with "<<quiz.trials()<<" questions and with a probability of guessing right of "<<quiz.success_fraction()*100<<" %"<<" or 1 in "<<static_cast<int>(1./quiz.success_fraction())<<endl;

Show a few probabilities of just guessing:

cout<<"Probability of getting none right is "<<pdf(quiz,0)<<endl;// 0.010023
cout<<"Probability of getting exactly one right is "<<pdf(quiz,1)<<endl;cout<<"Probability of getting exactly two right is "<<pdf(quiz,2)<<endl;intpass_score=11;cout<<"Probability of getting exactly "<<pass_score<<" answers right by chance is "<<pdf(quiz,pass_score)<<endl;cout<<"Probability of getting all "<<questions<<" answers right by chance is "<<pdf(quiz,questions)<<endl;

Probability of getting none right is 0.0100226
Probability of getting exactly one right is 0.0534538
Probability of getting exactly two right is 0.133635
Probability of getting exactly 11 right is 0.000247132
Probability of getting exactly all 16 answers right by chance is 2.32831e-010

cout<<"Probability of getting none or one right is "<<pdf(quiz,0)+pdf(quiz,1)<<endl;

Probability of getting none or one right is 0.0634764

But if more than a couple of scores are involved, it is more convenient
(and may be more accurate) to use the Cumulative Distribution Function
(cdf) instead:

cout<<"Probability of getting none or one right is "<<cdf(quiz,1)<<endl;

Probability of getting none or one right is 0.0634764

Since the cdf is inclusive, we can get the probability of getting
up to 10 right ( <= )

cout<<"Probability of getting <= 10 right (to fail) is "<<cdf(quiz,10)<<endl;

Probability of getting <= 10 right (to fail) is 0.999715

To get the probability of getting 11 or more right (to pass), it
is tempting to use

1-cdf(quiz,10)

to get the probability of > 10

cout<<"Probability of getting > 10 right (to pass) is "<<1-cdf(quiz,10)<<endl;

Probability of getting > 10 right (to pass) is 0.000285239

But this should be resisted in favor of using the complement function.
Why complements?

cout<<"Probability of getting > 10 right (to pass) is "<<cdf(complement(quiz,10))<<endl;

Probability of getting > 10 right (to pass) is 0.000285239

And we can check that these two, <= 10 and > 10, add up to
unity.

BOOST_ASSERT((cdf(quiz,10)+cdf(complement(quiz,10)))==1.);

If we want a < rather than a <= test, because the CDF is inclusive,
we must subtract one from the score.

cout<<"Probability of getting less than "<<pass_score<<" (< "<<pass_score<<") answers right by guessing is "<<cdf(quiz,pass_score-1)<<endl;

Probability of getting less than 11 (< 11) answers right by guessing is 0.999715

and similarly to get a >= rather than a > test we also need
to subtract one from the score (and can again check the sum is unity).
This is because if the cdf is inclusive, then
its complement must be exclusive otherwise there
would be one possible outcome counted twice!

cout<<"Probability of getting at least "<<pass_score<<"(>= "<<pass_score<<") answers right by guessing is "<<cdf(complement(quiz,pass_score-1))<<", only 1 in "<<1/cdf(complement(quiz,pass_score-1))<<endl;BOOST_ASSERT((cdf(quiz,pass_score-1)+cdf(complement(quiz,pass_score-1)))==1);

Probability of getting at least 11 (>= 11) answers right by guessing is 0.000285239, only 1 in 3505.83

First, calculate the probability of getting a range of guesses right,
by adding the exact probabilities of each from low ... high.

intlow=3;// Getting at least 3 right.
inthigh=5;// Getting as most 5 right.
doublesum=0.;for(inti=low;i<=high;i++){sum+=pdf(quiz,i);}cout.precision(4);cout<<"Probability of getting between "<<low<<" and "<<high<<" answers right by guessing is "<<sum<<endl;// 0.61323

Probability of getting between 3 and 5 answers right by guessing is 0.6132

Or, usually better, we can use the difference of cdfs instead:

cout<<"Probability of getting between "<<low<<" and "<<high<<" answers right by guessing is "<<cdf(quiz,high)-cdf(quiz,low-1)<<endl;// 0.61323

Probability of getting between 3 and 5 answers right by guessing is 0.6132

And we can also try a few more combinations of high and low choices:

low=1;high=6;cout<<"Probability of getting between "<<low<<" and "<<high<<" answers right by guessing is "<<cdf(quiz,high)-cdf(quiz,low-1)<<endl;// 1 and 6 P= 0.91042
low=1;high=8;cout<<"Probability of getting between "<<low<<" and "<<high<<" answers right by guessing is "<<cdf(quiz,high)-cdf(quiz,low-1)<<endl;// 1 <= x 8 P = 0.9825
low=4;high=4;cout<<"Probability of getting between "<<low<<" and "<<high<<" answers right by guessing is "<<cdf(quiz,high)-cdf(quiz,low-1)<<endl;// 4 <= x 4 P = 0.22520

Probability of getting between 1 and 6 answers right by guessing is 0.9104
Probability of getting between 1 and 8 answers right by guessing is 0.9825
Probability of getting between 4 and 4 answers right by guessing is 0.2252

Using moments of the distribution, we can say more about the spread
of results from guessing.

cout<<"By guessing, on average, one can expect to get "<<mean(quiz)<<" correct answers."<<endl;cout<<"Standard deviation is "<<standard_deviation(quiz)<<endl;cout<<"So about 2/3 will lie within 1 standard deviation and get between "<<ceil(mean(quiz)-standard_deviation(quiz))<<" and "<<floor(mean(quiz)+standard_deviation(quiz))<<" correct."<<endl;cout<<"Mode (the most frequent) is "<<mode(quiz)<<endl;cout<<"Skewness is "<<skewness(quiz)<<endl;

By guessing, on average, one can expect to get 4 correct answers.
Standard deviation is 1.732
So about 2/3 will lie within 1 standard deviation and get between 3 and 5 correct.
Mode (the most frequent) is 4
Skewness is 0.2887