The problem in brief
A crew must pick rocket components out of available ones, and the order in which they are picked does not matter. Your program reads the two natural numbers and and prints the number of possible choices. This is the binomial coefficient , the most frequently used number in combinatorics and in probability. The only real difficulties are computing it without overflow or rounding errors, and handling edge cases.
How you are scored
The judge compares your printed integer with the exact answer on hidden tests (time limit 1 s, memory 64 MB). The statement gives no upper bound for , so the answer may be a huge integer: an exact computation is the target.
The key idea
Count ordered choices, then divide by the orderings you over-counted. Picking the components one at a time, in order, there are choices for the first, for the second, ..., for the -th. That counts each set of components once per possible order, that is times. Hence
Two more facts make the computation clean:
- Symmetry: choosing the components you take is the same as choosing the you leave, so . Always compute with the smaller of and .
- Pascal's rule: (a given component is either taken or not). It gives a dynamic-programming alternative and a good self-check.

The figure shows why overflow matters: already has 30 digits. In C++ or Java, a 64-bit integer overflows from on, and computing first overflows much earlier (). Using floating point (math.factorial(n) / ... or scipy.special.comb without exact=True) silently loses digits beyond about .
The full solution
Multiply and divide alternately, so the running value stays an exact integer and never grows much bigger than the answer:
def comb(n, k):
if k < 0 or k > n:
return 0 # no way to choose more than you have
k = min(k, n - k) # symmetry
r = 1
for i in range(1, k + 1):
r = r * (n - k + i) // i # r is now C(n-k+i, i), always an integer
return r
Why is the floor division exact? After step , , which is an integer, and . So is always divisible by . The loop runs times; Python integers have arbitrary precision, so the answer is exact even with thousands of digits. (In Python 3.8+ math.comb(n, k) does the same thing; knowing how it works matters when you code in another language or need the value modulo a prime.)
Edge cases: or give 1; gives 0.
solution.py --check verifies the function against brute-force enumeration of all subsets for , against math.comb and Pascal's rule on 2000 random cases with .
Results
| approach | correct on large tests? | why |
|---|---|---|
| multiplicative formula with exact integers | yes | exact, steps |
math.comb | yes | same algorithm, built in |
| with Python integers | yes, but slower | huge intermediate numbers |
| same with 64-bit integers (C++) | no, from | overflows |
| floating-point factorials | no, from about | only 53 bits of mantissa |
| enumerate all subsets | no | subsets |
What to remember
- Count ordered selections, divide by the number of orderings: this reasoning recovers and many other counting formulas.
- Use symmetry, and alternate multiplications and divisions, so that every intermediate value is an exact integer.
- Combinatorial numbers explode: never compute factorials in fixed-size integers or floats when an exact answer is required.
- In ML, is everywhere: the number of feature subsets of size (why exhaustive feature selection is hopeless), the binomial distribution behind accuracy confidence intervals, the number of pairs in a similarity matrix.