Issue
The code works well now. You want to participate in the 6 out of 49 games of chance with a single (simple) option and you want to know your chances of winning:
Category I (6 numbers)
Category II (5 numbers)
Category III (4 numbers)
Write a console application that calculates your chances of winning the lottery. Generalize the solution to work for any combination of total balls, balls drawn, and category.
The application takes as input the total number of balls, the number of balls drawn, and the category and then prints out the winning odds with an accuracy of 10 decimal places if only one variant is played.
Example:
For entry data:
40
5
II
The console will display:
0.0002659542
Here is the formula:
kCj * (n-j)C(k-j) / nCk
which should translate to this
k!/(j!*(k-j)!) * (n-j)!/((k-j)!*(n-k)!) / n!/(k!*(n-k)!)
Here is my code:
using System;
class Program
{
static void Main()
{
decimal totalNumbers = Convert.ToDecimal(Console.ReadLine()); // total numbers
decimal extractedNumber = Convert.ToDecimal(Console.ReadLine()); // extracted numbers
string numbersCategory = Console.ReadLine(); // numbers that have to be extracted
decimal temporaryExtractedNumber; // this will be used to set the category
const decimal first = 1;
const decimal second = 2;
decimal a;
decimal b;
decimal c;
decimal result;
if (numbersCategory == "I")
{
temporaryExtractedNumber = extractedNumber;
}
if (numbersCategory == "II")
{
temporaryExtractedNumber = extractedNumber - first;
}
if (numbersCategory == "III")
{
temporaryExtractedNumber = extractedNumber - second;
}
a = NCK(totalNumbers, extractedNumber, temporaryExtractedNumber);
b = NCK(totalNumbers, totalNumbers - extractedNumber, extractedNumber - temporaryExtractedNumber);
c = NCK(totalNumbers, totalNumbers, extractedNumber);
result = a * b / c; // this is the magic formula
Console.WriteLine(result.ToString("F10"));
}
static decimal NCK(decimal totalNumbers, decimal extractedNumber, decimal temporaryExtractedNumber)
{
if (extractedNumber == temporaryExtractedNumber)
{
return 1;
}
if (extractedNumber - temporaryExtractedNumber == 0)
{
return 1;
}
if (temporaryExtractedNumber == 0)
{
return 1;
}
decimal temp1;
if (extractedNumber < temporaryExtractedNumber)
{
temp1 = extractedNumber;
extractedNumber = temporaryExtractedNumber;
temporaryExtractedNumber = temp1;
}
decimal kj = extractedNumber - temporaryExtractedNumber;
if (temporaryExtractedNumber < kj)
{
temp1 = temporaryExtractedNumber;
temporaryExtractedNumber = kj;
kj = temp1;
}
decimal result1 = 1;
for (decimal i = temporaryExtractedNumber + 1; i <= extractedNumber; i++)
{
result1 *= i;
}
decimal result2 = 1;
for (decimal i = 1; i <= kj; i++)
{
result2 *= i;
}
return result1 / result2;
}
}
Solution
Your formula is incorrect.
The probability of guessing exactly j correct numbers from a draw of k numbers selected from n possibilities is:
In your formula, the n−k in the second binomial coefficient has been replaced with n−j, leading to overcounting. For clarity, numerator of the fraction is the number of subsets where j numbers are drawn from the k winning numbers and k−j numbers are drawn from the n−k not-winning numbers.
With that minor change, you’ll get the expected probability computation.
I only feel a little bad using codecogs. Client-side rendering with MathJax would be a lot better, IMHO, but that’s not going to happen. In case Codecogs vanishes or overloads, here’s the PNG:
Answered By – rici
Answer Checked By – Marilyn (BugsFixing Volunteer)