Python Program to Find nCr and nPr
nCr = factorial(n) // (factorial(r) * factorial(n - r)) and nPr = factorial(n) // factorial(n - r), where factorial is the product of all positive integers up to a number.Examples
How to Think About It
Algorithm
Code
def factorial(num): result = 1 for i in range(1, num + 1): result *= i return result def nCr(n, r): return factorial(n) // (factorial(r) * factorial(n - r)) def nPr(n, r): return factorial(n) // factorial(n - r) n = 5 r = 3 print(f"nCr = {nCr(n, r)}, nPr = {nPr(n, r)}")
Dry Run
Let's trace n=5 and r=3 through the code
Calculate factorial(5)
factorial(5) = 1*2*3*4*5 = 120
Calculate factorial(3)
factorial(3) = 1*2*3 = 6
Calculate factorial(2)
factorial(2) = 1*2 = 2
Calculate nCr
nCr = 120 // (6 * 2) = 120 // 12 = 10
Calculate nPr
nPr = 120 // 2 = 60
| Step | Operation | Value |
|---|---|---|
| 1 | factorial(5) | 120 |
| 2 | factorial(3) | 6 |
| 3 | factorial(2) | 2 |
| 4 | nCr = 120 // (6*2) | 10 |
| 5 | nPr = 120 // 2 | 60 |
Why This Works
Step 1: Factorial Calculation
The factorial function multiplies all numbers from 1 up to the given number to get the factorial value.
Step 2: Calculate nCr
nCr uses the formula factorial(n) // (factorial(r) * factorial(n - r)) to count combinations without order.
Step 3: Calculate nPr
nPr uses the formula factorial(n) // factorial(n - r) to count permutations with order.
Alternative Approaches
import math def nCr(n, r): return math.comb(n, r) def nPr(n, r): return math.perm(n, r) n = 5 r = 3 print(f"nCr = {nCr(n, r)}, nPr = {nPr(n, r)}")
def factorial(num): if num == 0 or num == 1: return 1 else: return num * factorial(num - 1) n = 5 r = 3 print(f"nCr = {factorial(n) // (factorial(r) * factorial(n - r))}, nPr = {factorial(n) // factorial(n - r)}")
Complexity: O(n) time, O(1) space
Time Complexity
Calculating factorial takes O(n) time because it multiplies numbers from 1 to n. Both nCr and nPr depend on factorial calculations.
Space Complexity
The space used is O(1) because calculations use a fixed amount of memory without extra data structures.
Which Approach is Fastest?
Using Python's built-in math.comb and math.perm is fastest and most efficient, as they are optimized in C.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Manual factorial loop | O(n) | O(1) | Learning and small inputs |
| Recursive factorial | O(n) | O(n) | Understanding recursion, smaller inputs |
| math.comb and math.perm | O(1) or optimized | O(1) | Production and large inputs |