@mbozzi: The instructions tell to use double (to avoid integer overflow).
@JStinsch: You already had:
1 2 3
|
double students = 12.0;
double teams;
double teamSize = 3.0;
|
The
n
is students.
The
r
is teamSize.
You could use a helper variable for
(n - r)
:
auto diff = students - teamSize;
Then you'll have:
teams = factorial(students) / factorial(teamSize) / factorial(diff);
Note that the input values (n and r) should probably be integers, for real life gets a bloody mess, if you can have 11.4 students ...
A floating point value is not good as a loop counter. Floating point math is not quite intuitive.
Keep the counter as int and make a double form it in the body of the loop, if necessary.
Making that function
double factorial(int)
and calling it three times is (ought to be) very clear. It is good practise to write that version.
Then consider efficiency
https://en.wikipedia.org/wiki/Factorial#Applications discusses your problem, but seems to compute less.
In this case
(n-r) > r
, because 9 > 3.
12!
--- = 10 * 11 * 12 = x
9! |
We did not compute three factorials. We did compute products of two series (consecutive numbers):
A product of serie that starts from 1 is factorial.
For that you could write a function that is more generic than the factorial():
double serieproduct( int first, int last );
In fact, the factorial could then be rewritten as:
1 2 3 4
|
double factorial( int k )
{
return serieproduct( 1, k );
}
|
Unlike calling factorial three times, the serieproduct() version requires checking what to compute.
Lets say that teamSize=8. Therefore, diff=4
We don't want to compute
We should compute
In other words, the use of
if else
(or ternary operator ?: ) is necessary.
Then again, as mbozzi did mention, you have to check that
0 < teamSize && teamSize <= students
before any computation. That is true for all approaches. There is no point to compute anything, if the input is nonsense.