math
CHAPTER 19 / 45
읽기 약 2분
FUNCTION
조합: 순서가 필요 없는 선택
핵심 개념
nCr = n!/(r!(n-r)!) — 팀 구성, 기능 조합 테스트, 로또. 파스칼의 삼각형 + itertools.combinations.
본문
조합 공식
nCr = nPr / r!
= n! / (r! × (n-r)!)
= "n개 중 r개 선택" (순서 무관)
예: 5명 중 3명 팀 구성
5C3 = 5! / (3! × 2!) = 120 / (6 × 2) = 10
성질:
nCr = nC(n-r) # 5C3 = 5C2
nC0 = nCn = 1 # 선택 안 함 / 모두 선택
nC(r-1) + nCr = (n+1)Cr # 파스칼 항등식Python itertools.combinations
import itertools, math
items = ['A', 'B', 'C', 'D', 'E']
# 5개 중 3개 조합
combos = list(itertools.combinations(items, 3))
for c in combos:
print(c)
# ('A', 'B', 'C')
# ('A', 'B', 'D')
# ('A', 'B', 'E')
# ('A', 'C', 'D')
# ('A', 'C', 'E')
# ('A', 'D', 'E')
# ('B', 'C', 'D')
# ('B', 'C', 'E')
# ('B', 'D', 'E')
# ('C', 'D', 'E')
# 총 5C3 = 10가지
print(math.comb(5, 3)) # 10 (Python 3.8+)
# 중복 허용 조합 (with replacement)
print(list(itertools.combinations_with_replacement('AB', 3)))
# [('A','A','A'), ('A','A','B'), ('A','B','B'), ('B','B','B')]파스칼의 삼각형
# C(n, r) 값들의 패턴 — 행 n, 열 r
# 각 칸 = 윗줄 두 칸의 합 (파스칼 항등식)
def pascal_triangle(rows=10):
triangle = [[1]]
for i in range(1, rows):
prev = triangle[-1]
new_row = [1] + [prev[j] + prev[j+1] for j in range(len(prev)-1)] + [1]
triangle.append(new_row)
return triangle
for row in pascal_triangle(8):
print(' '.join(f"{n:>4}" for n in row).center(60))
# 출력:
# 1
# 1 1
# 1 2 1
# 1 3 3 1
# 1 4 6 4 1
# 1 5 10 10 5 1
# 1 6 15 20 15 6 1
# 1 7 21 35 35 21 7 1실전 — 팀 구성
# 10명 중 5명 팀 구성 — 가능한 조합 수
print(math.comb(10, 5)) # 252
# 3개 부서에서 각 1명씩 선발 (조합의 곱)
dev = ['Alice', 'Bob'] # 2명
design = ['Carol', 'Dave', 'Eve'] # 3명
pm = ['Frank'] # 1명
total_teams = math.comb(2, 1) * math.comb(3, 1) * math.comb(1, 1)
print(f"가능한 팀: {total_teams}가지") # 6
# 모든 조합 직접 생성
import itertools
for team in itertools.product(dev, design, pm):
print(team)실전 — 로또 확률
# 한국 로또: 1~45 중 6개 선택, 순서 무관
total = math.comb(45, 6)
print(f"가능한 조합: {total:,}") # 8,145,060
# 1등 당첨 확률
prob_1st = 1 / total
print(f"1등: 1 / {total:,} = {prob_1st:.10f}") # 0.0000001228 (약 800만분의 1)
# 5등(3개 일치)
# 당첨 번호 6개 중 3개 + 비당첨 39개 중 3개
prob_5th = (math.comb(6, 3) * math.comb(39, 3)) / total
print(f"5등 (3개 일치): {prob_5th:.4f} = {prob_5th*100:.2f}%") # 1.76%
# 실제 평균 1등까지 걸리는 횟수
import random
random.seed(42)
winning = sorted(random.sample(range(1, 46), 6))
print(f"\n당첨 번호: {winning}")
trials = 0
while True:
trials += 1
pick = sorted(random.sample(range(1, 46), 6))
if pick == winning:
print(f"{trials:,}번째 시도 만에 당첨")
break
if trials >= 10_000_000:
print(f"1000만 번 시도 중 당첨 없음 (확률: {prob_1st})")
break실전 — 기능 조합 테스트
# 4개 기능을 켜고/끄는 모든 조합 테스트 = 2^4 = 16
# 단, 항상 켜져야 하는 기본 기능 1개 + 나머지 3개 → 2^3 = 8
features = ['auth', 'cache', 'cdn', 'rate_limit']
# 각 기능을 켤지 말지 — 부분집합 모두
for r in range(len(features) + 1):
for combo in itertools.combinations(features, r):
print(f"활성: {list(combo)}")
# 16가지 (빈 조합 포함)
# 페어와이즈(Pairwise) 테스트 — 조합 폭발 방지
# 4개 변수 × 각 2값 = 2^4 = 16가지 중 모든 쌍을 커버하는 최소 조합
# pip install allpairspy
from allpairspy import AllPairs
params = [['on', 'off']] * 4
print("\n페어와이즈 조합:")
for i, pair in enumerate(AllPairs(params)):
print(f" {i+1}: {pair}")
# 약 5~6개 조합으로 모든 쌍 커버다음 챕터
CH.20 "재귀와 팩토리얼" — n! = n × (n-1)! 패턴과 재귀 함수의 수학적 기반.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 A/B 테스트 변수 N개의 조합 폭발을 분석해서 페어와이즈 테스트로 줄인 결과와 커버리지를 보고해줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
한국 게임/소셜 플랫폼의 매칭 시스템 조합 알고리즘 사례 5개를 비교 분석해줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 데이터에서 가능한 모든 조합을 분석해서 핵심 그룹 Top 10과 비즈니스 임팩트를 시뮬레이션해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 코딩 테스트에서 조합론 출제 빈도와 실전 활용도를 솔직히 알려줘.
⭐ 이것만 기억하세요
조합: 순서가 필요 없는 선택은 이 3가지만 확실히 잡으세요
1.조합 nCr = n!/(r!(n-r)!) — 순서 무관한 선택의 경우의 수
2.파스칼의 삼각형은 nCr 값들의 패턴 — 각 칸 = 윗줄 두 칸의 합
3.다음 챕터 CH.20에서 재귀와 팩토리얼 — n!의 수학적 정의가 재귀 함수의 본질
공유하기
진행도 19 / 45