Skip to content

Instantly share code, notes, and snippets.

@sooop
Last active August 29, 2015 14:09
Show Gist options
  • Save sooop/48c977dfce69302f93e4 to your computer and use it in GitHub Desktop.
Save sooop/48c977dfce69302f93e4 to your computer and use it in GitHub Desktop.
순열/조합을 구하는 함수
def combinations(iterable, r):
# combinations('ABCD', 2) -> AB AC AD BC BD CD
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
def combinations2(iterable, r):
pool = tuple(iterable)
n = len(pool)
for indices in permutations(range(n), r):
if sorted(indices) == list(indices):
yield tuple(pool[i] for i in indices)
# 순열을 구하는 함수
# 재귀를 사용하지 않고
# 제너레이터를 리턴함.
def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = range(n)
cycles = range(n, n-r, -1)
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return
# 데카르트 곱을 이용하는 방법
# product 함수는 주어진 연속열의 데카르트 곱을 생성한다.
def product(*args, **kwgs):
pools = map(tuple, args) * kwgs.get('repeat', 1)
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
# 데카르트 곱을 사용하여 r 개의 원소를 취했을 때
# 이를 출력하면 사전식 순열이 된다.
def permutations2(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
for indices in product(range(n), repeat=r):
if len(set(indices)) == r:
yield tuple(pool[i] for i in indices)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment