문제 분해 — 프로그램은 조각으로 만든다
어떤 프로그래머도 큰 프로그램을 한 번에 만들지 않습니다. 바로 만들 수 있는 작은 조각으로 나눈 뒤, 하나씩 완성합니다. 이 장에서는 그 나누는 기술 — 문제 분해를 훈련합니다.
1개념 정리
분해가 필요한 이유 — 작은 조각은 만들기 쉽고, 확인하기 쉽고, 고치기 쉽기 때문입니다.
예를 들어 "퀴즈 게임 프로그램"을 통으로 한 번에 만들 수 없지만, "문제 하나를 화면에 보여주기" 조각은 바로 만들 수 있습니다.
프로그램 개발에서도 이 조각 하나하나가 함수(function) 하나가 됩니다.
다만 아무렇게나 나눈 것은 좋은 분해가 아닙니다.
좋은 분해는 아래 세 가지 기준을 갖추어야 합니다.
| 기준 | 나쁜 분해 ✗ | 좋은 분해 ✓ | 확인하는 법 |
|---|---|---|---|
| 1. 빠짐없이 | 숫자 맞히기 게임을 [입력받기, 힌트 주기]로만 나눔 — 정답을 정하는 조각이 없음 | [정답 정하기, 입력받기, 비교하기, 힌트 주기] | 조각을 전부 합쳐 원래 문제가 완성되는지 확인 |
| 2. 겹치지 않게 | [결과 보여주기, 누가 이겼는지 화면에 띄우기] — 말만 다른 같은 일 | [누가 이겼는지 가리기, 결과 보여주기] | 두 조각이 하는 일을 각각 한 문장으로 써서 비교 |
| 3. 바로 시작할 수 있게 | [게임을 재미있게 만들기] — 읽어도 첫 동작이 떠오르지 않음 | [점수를 1 올리기], [효과음 재생하기] | 조각을 읽고 "지금 당장 할 첫 동작"이 떠오르는지 확인 — 떠오르지 않으면 한 번 더 나눔 |
분해를 언제 멈출지는 셋째 기준이 정합니다. 모든 조각이 "바로 시작할 수 있는 크기"가 될 때까지 나누기를 반복합니다.
2예제 풀이 — 숫자 맞히기 게임 분해
문제: "컴퓨터가 1~100 사이에서 몰래 정한 숫자를, 사용자가 힌트를 받으며 맞히는 게임"을 만들려고 합니다. 이 문제를 분해하는 과정을 처음부터 끝까지 보여줍니다.
한 문장으로 써 보면 무엇을 만들어야 하는지가 정확해지고, 빠진 조각을 나중에 찾는 기준이 됩니다.
2. 사용자에게 추측 숫자를 입력받는다
3. 추측과 정답을 비교한다
4. 비교 결과에 따라 "더 큽니다 / 더 작습니다"를 보여준다
5. 정답을 맞힐 때까지 2~4를 반복한다
6. 맞히면 축하 메시지와 시도 횟수를 보여준다
※ 조각마다 "~한다"로 끝나는 동작 한 개만 담습니다. 코드로 옮기면 조각 하나가 함수 하나가 됩니다.
겹치지 않게: 여섯 조각이 하는 일이 모두 다릅니다. 3(비교)과 4(보여주기)를 하나로 합치지 않은 것에 주의합니다 — 비교하는 일과 보여주는 일은 서로 다른 일입니다.
바로 시작: 여섯 조각 모두 읽는 즉시 첫 동작이 떠오릅니다. 점검 통과 — 분해 완료입니다.
3따라 하기 — 가위바위보 게임 분해
이번에는 "컴퓨터와 가위바위보를 해서 먼저 2번 이기는 쪽이 승리하는 게임"을 예제와 같은 순서로 함께 분해합니다. 물음에 하나씩 답하면서 나아갑니다.
2. 컴퓨터의 손 모양을 무작위(랜덤)로 정한다
3. 두 손 모양을 비교해 이번 판에 누가 이겼는지 가린다
4. 이번 판 결과와 지금까지의 승수를 보여준다
5. 어느 한쪽이 2번 이길 때까지 1~4를 반복한다
6. 마지막 승자를 보여준다
점검: 한 문장 목표("컴퓨터와 가위바위보를 해서 먼저 2번 이기는 쪽이 승리한다")와 비교하면 빠진 것이 없고, 여섯 조각이 하는 일이 모두 다르며, 모든 조각이 읽는 즉시 시작할 수 있는 크기입니다. "정정당당한 게임이 되게 한다" 같은 말이 조각 목록에 없는 것을 눈여겨봅니다 — 마음가짐이나 목표는 조각이 아닙니다.
4스스로 풀기
난이도를 골라 아래 입력 칸에 직접 분해를 씁니다. 다 쓴 뒤 예시 답안과 비교하고, 점검 목록으로 스스로 확인합니다. 기본부터 차례로 푸는 것이 좋습니다.
※ 입력한 내용은 저장되지 않습니다. 남기고 싶으면 공책이나 문서에 옮겨 둡니다.
예시 답안 보기 — 반드시 먼저 쓴 뒤에 엽니다
① 한 문장: 반 학생 이름을 순서대로 하나씩 보여주고, 출석/결석 입력을 받아 기록한 뒤, 마지막에 출석 결과표를 보여준다.
② 입력: 학생 명단, 출석/결석 대답 / 처리: 다음 이름 고르기, 기록하기, 명단 끝까지 반복 / 출력: 이름 표시, 결과표
2. 명단에서 다음 이름을 화면에 보여준다
3. 출석/결석 입력을 받는다
4. 입력받은 결과를 기록한다
5. 명단이 끝날 때까지 2~4를 반복한다
6. 출석 결과표를 보여준다
예시와 표현이 달라도 괜찮습니다. 아래 점검 목록을 통과하는지가 기준입니다.
※ 입력한 내용은 저장되지 않습니다. 남기고 싶으면 공책이나 문서에 옮겨 둡니다.
예시 답안 보기 — 반드시 먼저 쓴 뒤에 엽니다
① 한 문장: 학급 문고의 책을 등록해 두고, 누가 어떤 책을 빌리고 반납했는지 기록하며, 현재 상태를 조회할 수 있게 한다.
1-1. 책 제목과 관리 번호를 입력받는다
1-2. 책 목록에 추가한다
[묶음 2] 대출 기능
2-1. 빌리는 사람 이름과 책 번호를 입력받는다
2-2. 그 책이 대출 가능한지 확인한다
2-3. 대출 기록을 남기고 책 상태를 '대출 중'으로 바꾼다
[묶음 3] 반납 기능
3-1. 반납할 책 번호를 입력받는다
3-2. 책 상태를 '대출 가능'으로 바꾸고 반납 날짜를 기록한다
[묶음 4] 조회 기능
4-1. 전체 책 목록과 상태를 보여준다
4-2. 특정 사람이 빌린 책을 찾아 보여준다
③ 기억해야 하는 정보: 책 목록(제목·관리 번호·상태), 대출 기록(누가·어떤 책을·언제 빌리고 반납했는지)
묶음을 등록/대출/반납/조회로 가른 기준은 "사용자가 하려는 일"입니다. 기준이 하나로 통일되면 조각이 겹치기 어렵습니다.
※ 입력한 내용은 저장되지 않습니다. 남기고 싶으면 공책이나 문서에 옮겨 둡니다.
예시 답안 보기 — 반드시 먼저 쓴 뒤에 엽니다
나누기 기준: 사용자가 하는 일의 순서(주운 물건을 올린다 → 잃어버린 사람이 찾는다 → 서로 연락해 돌려받는다)
1-1. 물건 정보 입력
1-1-1. 사진을 찍어 올린다 (데이터: 사진 파일)
1-1-2. 물건 종류·주운 장소·날짜를 고른다 (데이터: 종류, 장소, 날짜)
1-2. 올린 물건 목록 관리
1-2-1. 새 물건을 목록에 추가한다 (데이터: 물건 목록)
1-2-2. 주인을 찾은 물건을 '해결됨'으로 표시한다 (데이터: 상태)
2. 검색 기능
2-1. 조건으로 찾기
2-1-1. 종류·장소·날짜로 목록을 거른다 (데이터: 검색 조건)
2-1-2. 결과를 최신 것부터 보여준다 (데이터: 늘어놓는 순서)
3. 연락 기능
3-1. 쪽지 보내기
3-1-1. 물건을 올린 사람에게 쪽지를 남긴다 (데이터: 쪽지 내용)
3-1-2. 새 쪽지가 오면 알림을 보여준다 (데이터: 알림 목록)
기준을 "화면 단위"나 "정보 종류"로 잡아도 좋은 답이 됩니다. 다만 기준은 하나로 통일해야 합니다 — 그래야 어떤 기능이 어느 가지에 들어갈지 헷갈리지 않습니다.
① 세 문제 중 어디에서 가장 막혔고, 무엇을 바꾸었을 때 풀렸습니까?
② 세 문제에서 공통으로 쓴 방법은 무엇입니까? (할 일 한 문장 → 입력·처리·출력 → 조각 목록 → 세 기준 점검 — 지금 한 이 사고가 바로 문제 분해입니다.)
③ 다음에 큰 문제를 만나면, 나누기 위해 무엇부터 하겠습니까?
더 알아보기 — 함수와 모듈, 응집과 결합, 분할정복
1. 조각의 실제 이름 — 함수와 모듈
이 장에서 만든 조각 목록은 실제 개발에서 그대로 함수 목록이 됩니다.
예제의 "추측과 정답을 비교한다"는 compare(guess, answer) 같은 함수 하나로 만들어집니다.
함수 여러 개가 모여 하나의 기능을 이루면 모듈(module)이라고 부릅니다 — 문제 2에서 만든 대출·반납 같은 묶음이 모듈에 해당합니다.
2. 좋은 분해의 전문 용어 — 응집과 결합
소프트웨어 공학에서는 좋은 분해를 두 낱말로 요약합니다.
높은 응집(cohesion): 조각 하나는 한 가지 일만 한다.
낮은 결합(coupling): 조각 하나를 고쳐도 다른 조각을 고칠 필요가 없다.
심화 문제의 점검 목록 마지막 두 항목이 바로 이 두 기준입니다.
3. 나누기를 끝까지 밀어붙이면 — 분할정복
문제를 절반으로 나누고, 그 절반을 또 나누는 일을 반복하는 해결 전략을 분할정복(divide and conquer)이라고 합니다.
정렬된 1,000쪽짜리 사전에서 낱말을 찾을 때 한가운데를 펼쳐 절반을 버리는 이진탐색이 대표 사례이며, 열 번 이내에 원하는 쪽에 도달합니다.
컴퓨터가 엄청난 양의 자료를 빠르게 정렬하고 찾아내는 알고리즘 대부분이 이 전략을 씁니다.
자가진단
개념을 새 상황에 적용하는 문제입니다. 답을 고르면 즉시 채점과 해설이 나옵니다. ↻ 다시를 눌러 여러 번 풀 수 있습니다.
핵심 정리
- 문제 분해는 큰 문제를 바로 시작할 수 있는 작은 문제로 나누는 일입니다. 코드로 옮기면 조각 하나가 함수 하나가 됩니다.
- 분해의 순서 — ① 할 일을 한 문장으로 쓰기 ② 입력·처리·출력으로 가르기 ③ "~한다" 동작 한 개짜리 조각 목록 만들기 ④ 세 기준으로 점검하기.
- 세 기준 — 빠짐없이 · 겹치지 않게 · 바로 시작할 수 있게. 읽어도 첫 동작이 떠오르지 않는 조각은 한 번 더 나눕니다.
이 장이 참고한 자료
- Hunsaker, E. (n.d.). Computational thinking. In The K-12 educational technology handbook. EdTech Books. https://edtechbooks.org/k12handbook/computational_thinking
- Jeong, G., Lash, T., & Israel, M. (2017). Helpful strategies for project planning during K-12 computer science instruction. Project TACTIC, Creative Technology Research Lab, University of Illinois. https://ctrl.education.illinois.edu/TACTICal/project-planning.html
- Liedahl, B. (2026, June 22). Teaching computational thinking without a computer. Edutopia. https://www.edutopia.org/article/teaching-computational-thinking-without-computer/