Can you explain this recursive "n choose k" code to me?

python, recursion

Solution

The recursion is based on a simple observation, for which I will give a combinatorial argument, as to why it is true, rather than a mathematical proof through formulae.

Whenever you choose `k` elements out of `n`, there are two cases:

- You choose element `#n`

- You don't choose element `#n`

Since these events are mutually exclusive, the total amount of combinations is given by the amount of combinations when choosing `#n`, and those when you don't choose `#n`.

Choosing element `#n`

Since we have already chosen one element, we need only choose another `k-1` elements. Also, since we have decided upon one element – as to whether it is included or not – already, we only need to consider the remaining `n-1` elements.

Thus, the amount of combinations for choosing element `#n` is given by

    subset(n - 1, k - 1)

Not choosing element `#n`

There are still `k` elements to choose, but since we have already made up our mind about element `#n`, there remain only `n - 1` elements to choose from. Thus:

    subset(n - 1, k)

The base case

The recursion uses the fact, that we can usually differentiate between two situations, solutions where element `n` is part of that solution, and those where it is not.

However, such a distinction can not always be made:

- When choosing all elements (corresponding to case `n == k` in code below)

- or when choosing no elements at all (corresponding to case `k == 0` in code below)

In these cases, there is only exactly one solution, hence

if k == 0:
    return 1
if n == k:
    return 1

Ensuring it works

To do that, we need to convince ourselves (or prove) that the base case is always hit at some point.

Let us assume, that `n < k` at some point. Since per our assumption, `n` was originally greater or equal to `k`, there must have been some point where `n = k`, because `n` and `k` decrease in unison or only `n` decreases by one, i.e. it follows

This implies, that there must have been a call to `subset(n - 1, k)` for it to happen, that `n` decreases below `k`. However, this is not possible since we have a base case on `n = k` where we return a constant `1`.

We conclude that either `n` decreases at some point such that `n = k`, or decrease in unison exactly `k` times such that `k = 0`.

Thus, the base case works.

Problem

Here is the code to a subset problem with arguments n and k. n represents the total number of students and k represents the amount of the students I want to get out of n. The code attempts to give the number of possible combinations of pulling k number of students out of n number of students. ``` def subset(n, k): if k == 0: return 1 if n == k: return 1 else: return subset(n-1, k-1) + subset(n-1, k) ``` I understand the first part of the recursive call, but I'm having trouble understanding the + subset(n-1, k) part. Can anyone explain this to me?

Original source