Skip to content

Instantly share code, notes, and snippets.

@craabreu
Created November 1, 2023 12:22
Show Gist options
  • Save craabreu/ebc108fab8d4f6735c4f51e3ae5f29b1 to your computer and use it in GitHub Desktop.
Save craabreu/ebc108fab8d4f6735c4f51e3ae5f29b1 to your computer and use it in GitHub Desktop.
Efficient, parallelization-friendly combination generator
import typing as t
import math
def combination(n: int, k: int, m: int) -> t.Generator[int, None, None]:
"""
Return the m-th combination (in lexicographic order) of the n integers from 0 to
n-1, taken k at a time.
"""
a, b, x = n, k + 1, math.comb(n, k)
comb_a_b = x * (n - k) // b
x -= m + 1
for b in range(k, 0, -1):
comb_a_b = comb_a_b * (b + 1) // a
a -= 1
while comb_a_b > x:
comb_a_b = comb_a_b * (a - b) // a
a -= 1
x -= comb_a_b
yield n - 1 - a
@craabreu
Copy link
Author

craabreu commented Nov 1, 2023

The code is adapted from this project, with additional tricks to avoid multiple evaluations of math.comb.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment