Skip to content

Commit 9523b68

Browse files
Add generalized nCr (combinations) calculator for real n and integer r (#13623)
* Create ncr_combinations.py * Update ncr_combinations.py * Update ncr_combinations.py * Update ncr_combinations.py * Update ncr_combinations.py * updating DIRECTORY.md --------- Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: cclauss <cclauss@users.noreply.github.com>
1 parent 2d75c9c commit 9523b68

2 files changed

Lines changed: 78 additions & 0 deletions

File tree

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@
815815
* [Modular Exponential](maths/modular_exponential.py)
816816
* [Monte Carlo](maths/monte_carlo.py)
817817
* [Monte Carlo Dice](maths/monte_carlo_dice.py)
818+
* [Ncr Combinations](maths/ncr_combinations.py)
818819
* [Number Of Digits](maths/number_of_digits.py)
819820
* Numerical Analysis
820821
* [Adams Bashforth](maths/numerical_analysis/adams_bashforth.py)

maths/ncr_combinations.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
Generalized combinations (n choose r) calculator for real total and integer choose.
3+
Wikipedia URL:
4+
https://en.wikipedia.org/wiki/Binomial_coefficient
5+
"""
6+
7+
from math import factorial as math_factorial
8+
9+
10+
def combinations(total: float, choose: int) -> float:
11+
"""
12+
Compute the number of combinations using the formula:
13+
14+
combinations = total * (total-1) * ... * (total-choose+1) / choose!
15+
16+
Parameters
17+
----------
18+
total : float
19+
Total number of items. Can be any real number.
20+
choose : int
21+
Number of items to select. Must be a non-negative integer.
22+
23+
Returns
24+
-------
25+
float
26+
The number of combinations.
27+
28+
Raises
29+
------
30+
ValueError
31+
If choose is not a non-negative integer.
32+
33+
Examples
34+
--------
35+
>>> combinations(5, 2)
36+
10.0
37+
>>> combinations(5.5, 2)
38+
12.375
39+
>>> combinations(10, 0)
40+
1.0
41+
>>> combinations(0, 0)
42+
1.0
43+
>>> combinations(5, -1)
44+
Traceback (most recent call last):
45+
...
46+
ValueError: choose must be a non-negative integer
47+
>>> combinations(5, 2.5)
48+
Traceback (most recent call last):
49+
...
50+
ValueError: choose must be a non-negative integer
51+
"""
52+
if not isinstance(choose, int) or choose < 0:
53+
raise ValueError("choose must be a non-negative integer")
54+
55+
if choose == 0:
56+
return 1.0
57+
58+
numerator = 1.0
59+
for i in range(choose):
60+
numerator *= total - i
61+
62+
denominator = math_factorial(choose)
63+
return numerator / denominator
64+
65+
66+
if __name__ == "__main__":
67+
import doctest
68+
69+
doctest.testmod()
70+
71+
# Example usage
72+
total_input = float(input("Enter total (real number): ").strip() or 0)
73+
choose_input = int(input("Enter choose (non-negative integer): ").strip() or 0)
74+
print(
75+
f"combinations({total_input}, {choose_input}) = "
76+
f"{combinations(total_input, choose_input)}"
77+
)

0 commit comments

Comments
 (0)