Workspace IndexAlgorithms › Day 18

Combinatorial Generation, Gray Codes, and Permutation Enumeration (TAOCP Vol. 4) TODO

Algorithms · Day 18 / 100 · A. Advanced Algorithms & Data Structures (Day 1-19)

Concept

Enumerating combinatorial objects means generating structures like subsets, combinations, or permutations one at a time, with no duplicates and none missed. A Gray code lists subsets so that any two consecutive codes differ in exactly one bit; the reflected binary Gray code is obtained simply by XORing index i with i shifted right by one. Permutations can be enumerated by producing the next permutation in lexicographic order, or by a method that swaps only two adjacent elements at each step to generate every permutation. The key benefit of this kind of minimal-change enumeration is that each next state's value can be computed incrementally from the previous one with a single small update. So the design goal isn't the cost of enumeration itself, but eliminating the cost of recomputing each state from scratch.

In test-vector generation, fuzzing-seed design, and exhaustive search of small state spaces, covering everything without duplication or omission is exactly what gives verification its confidence, and minimal-change ordering removes the cost of rewinding state.

Code & Formula

# 조합 생성·그레이 코드 — 반사 이진 그레이 코드를 생성하고 인접 코드의 해밍 거리가 항상 1임을 검증한다.

def gray_code(n):
    return [i ^ (i >> 1) for i in range(1 << n)]      # i와 i>>1의 XOR

def hamming_distance(a, b):
    return bin(a ^ b).count("1")

def to_bits(x, n):
    return format(x, f"0{n}b")

n = 4
codes = gray_code(n)

# 인접 코드가 정확히 1비트만 다른지 검증 (원형으로 마지막→처음도 포함)
distances = [hamming_distance(codes[i], codes[(i + 1) % len(codes)]) for i in range(len(codes))]
assert all(d == 1 for d in distances), "그레이 코드 인접 거리 위반!"

# 그레이 코드 순서로 만든 부분집합과 단순 이진 카운팅 순서로 만든 부분집합이
# "집합으로서는" 동일한지 확인 (순서만 다르고 원소 전체는 같아야 함)
binary_order = list(range(1 << n))
assert set(codes) == set(binary_order)

print(f"n={n} 그레이 코드 ({len(codes)}개):")
for i, c in enumerate(codes):
    prev_dist = distances[i - 1] if i else distances[-1]
    print(f"  step {i:2d}: {to_bits(c, n)}  (직전과 해밍거리={prev_dist})")
print("모든 인접 쌍의 해밍 거리 == 1:", all(d == 1 for d in distances))
print("이진 카운팅과 원소 집합 동일:", set(codes) == set(binary_order))

Exercise

Generate an n-bit Gray code using the XOR formula and unit-test that the Hamming distance between adjacent codes is always 1; then confirm that the same set of subsets, generated instead by plain binary counting, matches it as a set.

Practical Connection

For logic with a small, finite number of conditions or permission-flag combinations, like settlement logic, exhaustive enumeration gives a stronger guarantee than random fuzzing — combinatorial enumeration becomes a practical tool for writing branch tests for smart contracts.

Where it lands in Jayverse

Key expressions

Words and phrases from this page worth keeping, with the Korean meaning and the sentence they come from.

Expression뜻 · 쓰이는 자리
from scratch처음부터(다시) · "eliminating the cost of recomputing each state from scratch"
minimal-change한 번에 최소한만 바뀌는(방식) · "minimal-change enumeration"
exhaustive search전수 탐색, 빠짐없이 다 뒤지는 탐색 · "exhaustive search of small state spaces"
rewind (state)상태를 되돌리다 · "removes the cost of rewinding state"
incrementally점진적으로, 조금씩 누적하며 · "computed incrementally from the previous one"
with no duplicates and none missed중복도 누락도 없이 · "one at a time, with no duplicates and none missed"
gives ... a stronger guarantee than~보다 더 강한 보장을 준다 · "exhaustive enumeration gives a stronger guarantee than random fuzzing"
TAOCP커누스의 저서 이름(The Art of Computer Programming) · 이 주제(조합 생성·그레이 코드)의 출처로 언급된 고전. "Permutation Enumeration (TAOCP Vol. 4)"

If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/dev-100-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.


한국어

조합 생성·그레이 코드·순열 열거 (TAOCP 4권) TODO

Algorithms · Day 18 / 100 · A. 고급 알고리즘·자료구조 (Day 1–19)

테스트 벡터·퍼징·상태 공간 탐색의 도구

개념

조합적 대상의 열거란 부분집합, 조합, 순열 같은 구조를 중복 없이 빠짐없이 하나씩 생성하는 기법이다. 그레이 코드는 연속한 두 코드가 정확히 한 비트만 다르도록 부분집합을 나열하는 순서이며, 반사 이진 그레이 코드는 인덱스 i에 대해 i와 i를 오른쪽으로 한 칸 시프트한 값의 XOR로 간단히 얻는다. 순열은 사전순으로 다음 순열을 만드는 방법이나, 매 단계 인접 두 원소만 교환하며 모든 순열을 생성하는 방식으로 열거할 수 있다. 이런 최소 변화 열거의 핵심 이점은 이전 상태에서 한 번의 작은 갱신으로 다음 상태의 평가값을 증분 계산할 수 있다는 것이다. 따라서 열거 자체의 비용보다 각 상태를 처음부터 다시 계산하는 비용을 없애는 것이 설계의 목표가 된다.

테스트 벡터 생성, 퍼징 시드 설계, 작은 상태 공간의 완전 탐색에서 중복이나 누락 없이 전수를 도는 것이 곧 검증의 신뢰도이고, 최소 변화 순서를 쓰면 상태 되감기 비용이 사라진다.

코드 · 수식

# 조합 생성·그레이 코드 — 반사 이진 그레이 코드를 생성하고 인접 코드의 해밍 거리가 항상 1임을 검증한다.

def gray_code(n):
    return [i ^ (i >> 1) for i in range(1 << n)]      # i와 i>>1의 XOR

def hamming_distance(a, b):
    return bin(a ^ b).count("1")

def to_bits(x, n):
    return format(x, f"0{n}b")

n = 4
codes = gray_code(n)

# 인접 코드가 정확히 1비트만 다른지 검증 (원형으로 마지막→처음도 포함)
distances = [hamming_distance(codes[i], codes[(i + 1) % len(codes)]) for i in range(len(codes))]
assert all(d == 1 for d in distances), "그레이 코드 인접 거리 위반!"

# 그레이 코드 순서로 만든 부분집합과 단순 이진 카운팅 순서로 만든 부분집합이
# "집합으로서는" 동일한지 확인 (순서만 다르고 원소 전체는 같아야 함)
binary_order = list(range(1 << n))
assert set(codes) == set(binary_order)

print(f"n={n} 그레이 코드 ({len(codes)}개):")
for i, c in enumerate(codes):
    prev_dist = distances[i - 1] if i else distances[-1]
    print(f"  step {i:2d}: {to_bits(c, n)}  (직전과 해밍거리={prev_dist})")
print("모든 인접 쌍의 해밍 거리 == 1:", all(d == 1 for d in distances))
print("이진 카운팅과 원소 집합 동일:", set(codes) == set(binary_order))

연습

n비트 그레이 코드를 XOR 공식으로 생성해 인접 코드의 해밍 거리가 항상 1임을 단위 테스트로 검증하고, 같은 부분집합 집합을 단순 이진 카운팅으로 생성한 결과와 집합으로서 동일한지 확인하라.

실무 · Verex 연결

여러 조건이 걸린 정산 로직이나 권한 플래그 조합처럼 경우의 수가 작고 유한한 영역은 무작위 퍼징보다 전수 열거가 더 강한 보장을 주므로, 조합 열거는 스마트 컨트랙트 분기 테스트를 짜는 실전 도구가 된다.

Jayverse에서의 위치

핵심 표현

이 페이지의 영어 본문에서 배울 만한 단어와 표현, 뜻과 나온 자리.

Expression뜻 · 쓰이는 자리
from scratch처음부터(다시) · "eliminating the cost of recomputing each state from scratch"
minimal-change한 번에 최소한만 바뀌는(방식) · "minimal-change enumeration"
exhaustive search전수 탐색, 빠짐없이 다 뒤지는 탐색 · "exhaustive search of small state spaces"
rewind (state)상태를 되돌리다 · "removes the cost of rewinding state"
incrementally점진적으로, 조금씩 누적하며 · "computed incrementally from the previous one"
with no duplicates and none missed중복도 누락도 없이 · "one at a time, with no duplicates and none missed"
gives ... a stronger guarantee than~보다 더 강한 보장을 준다 · "exhaustive enumeration gives a stronger guarantee than random fuzzing"
TAOCP커누스의 저서 이름(The Art of Computer Programming) · 이 주제(조합 생성·그레이 코드)의 출처로 언급된 고전. "Permutation Enumeration (TAOCP Vol. 4)"

공부한 날 원본 커리큘럼(docs/knowledge/dev-100-curriculum.md)의 이 줄에 노트 링크와 ✅ 를 붙이면, 이 자리는 노트 본문으로 바로 이어집니다. 노트 없이 이 페이지에 바로 적어도 됩니다 — 다만 다시 생성하면 덮어쓰이므로, 남길 글은 docs/algorithms/ 의 마크다운으로 쓰는 편이 안전합니다.

← 1070. 병렬 알고리즘 모델1072. [복습] 알고리즘 선택의 실전 기준표 →