학습자료 컴퓨팅 사고력 워크북 01 문제 분해

문제 분해 — 프로그램은 조각으로 만든다

어떤 프로그래머도 큰 프로그램을 한 번에 만들지 않습니다. 바로 만들 수 있는 작은 조각으로 나눈 뒤, 하나씩 완성합니다. 이 장에서는 그 나누는 기술 — 문제 분해를 훈련합니다.

1개념 정리

문제 분해 (decomposition)
크고 복잡한 문제를, 바로 해결을 시작할 수 있는 작은 문제로 나누는 것.

분해가 필요한 이유 — 작은 조각은 만들기 쉽고, 확인하기 쉽고, 고치기 쉽기 때문입니다.

예를 들어 "퀴즈 게임 프로그램"을 통으로 한 번에 만들 수 없지만, "문제 하나를 화면에 보여주기" 조각은 바로 만들 수 있습니다.

프로그램 개발에서도 이 조각 하나하나가 함수(function) 하나가 됩니다.

다만 아무렇게나 나눈 것은 좋은 분해가 아닙니다.

좋은 분해는 아래 세 가지 기준을 갖추어야 합니다.

기준나쁜 분해 좋은 분해 확인하는 법
1. 빠짐없이 숫자 맞히기 게임을 [입력받기, 힌트 주기]로만 나눔 — 정답을 정하는 조각이 없음 [정답 정하기, 입력받기, 비교하기, 힌트 주기] 조각을 전부 합쳐 원래 문제가 완성되는지 확인
2. 겹치지 않게 [결과 보여주기, 누가 이겼는지 화면에 띄우기] — 말만 다른 같은 일 [누가 이겼는지 가리기, 결과 보여주기] 두 조각이 하는 일을 각각 한 문장으로 써서 비교
3. 바로 시작할 수 있게 [게임을 재미있게 만들기] — 읽어도 첫 동작이 떠오르지 않음 [점수를 1 올리기], [효과음 재생하기] 조각을 읽고 "지금 당장 할 첫 동작"이 떠오르는지 확인 — 떠오르지 않으면 한 번 더 나눔

분해를 언제 멈출지는 셋째 기준이 정합니다. 모든 조각이 "바로 시작할 수 있는 크기"가 될 때까지 나누기를 반복합니다.


2예제 풀이 — 숫자 맞히기 게임 분해

문제: "컴퓨터가 1~100 사이에서 몰래 정한 숫자를, 사용자가 힌트를 받으며 맞히는 게임"을 만들려고 합니다. 이 문제를 분해하는 과정을 처음부터 끝까지 보여줍니다.

단계 1
프로그램이 할 일을 한 문장으로 씁니다
"컴퓨터가 1~100 사이 숫자를 하나 정하면, 사용자가 그 숫자를 맞힐 때까지 추측을 입력하고, 컴퓨터는 매번 '더 큽니다/더 작습니다' 힌트를 준다."
한 문장으로 써 보면 무엇을 만들어야 하는지가 정확해지고, 빠진 조각을 나중에 찾는 기준이 됩니다.
단계 2
입력 · 처리 · 출력으로 가릅니다
프로그램 분해의 기본 틀입니다. 프로그램은 무엇이든 받아서(입력) → 계산하고(처리) → 보여줍니다(출력).
입력사용자의 추측 숫자 처리정답 정하기 · 추측과 정답 비교 · 맞힐 때까지 반복 출력힌트 문구 · 정답 축하 메시지 · 시도 횟수
단계 3
바로 만들 수 있는 조각 목록으로 나눕니다
단계 2의 틀을 채우면서, 각 조각이 셋째 기준(바로 시작)을 통과할 때까지 나눕니다.
1. 1~100 사이에서 정답을 무작위(랜덤)로 정한다
2. 사용자에게 추측 숫자를 입력받는다
3. 추측과 정답을 비교한다
4. 비교 결과에 따라 "더 큽니다 / 더 작습니다"를 보여준다
5. 정답을 맞힐 때까지 2~4를 반복한다
6. 맞히면 축하 메시지와 시도 횟수를 보여준다
※ 조각마다 "~한다"로 끝나는 동작 한 개만 담습니다. 코드로 옮기면 조각 하나가 함수 하나가 됩니다.
단계 4
세 기준으로 점검합니다
빠짐없이: 단계 1의 문장과 비교합니다 — 정답 정하기(1), 추측 입력(2), 힌트(3~4), 맞힐 때까지(5), 끝(6). 빠진 것이 없습니다.
겹치지 않게: 여섯 조각이 하는 일이 모두 다릅니다. 3(비교)과 4(보여주기)를 하나로 합치지 않은 것에 주의합니다 — 비교하는 일과 보여주는 일은 서로 다른 일입니다.
바로 시작: 여섯 조각 모두 읽는 즉시 첫 동작이 떠오릅니다. 점검 통과 — 분해 완료입니다.

3따라 하기 — 가위바위보 게임 분해

이번에는 "컴퓨터와 가위바위보를 해서 먼저 2번 이기는 쪽이 승리하는 게임"을 예제와 같은 순서로 함께 분해합니다. 물음에 하나씩 답하면서 나아갑니다.

물음 1 · 단계 2 — 입력 찾기이 게임에서 프로그램이 사용자에게 받아야 하는 입력은 무엇입니까?
물음 2 · 단계 3 — 처리 조각 고르기다음 후보 중 이 게임의 조각으로 알맞은 것 4개를 고릅니다. 나머지 2개는 셋째 기준(바로 시작)에 걸리는 가짜 조각입니다.
마무리 · 단계 3~4 — 완성 분해와 점검두 물음의 답을 반영한 완성 분해입니다. 버튼을 눌러 내 생각과 비교해 봅시다.
1. 사용자에게 손 모양(가위/바위/보)을 입력받는다
2. 컴퓨터의 손 모양을 무작위(랜덤)로 정한다
3. 두 손 모양을 비교해 이번 판에 누가 이겼는지 가린다
4. 이번 판 결과와 지금까지의 승수를 보여준다
5. 어느 한쪽이 2번 이길 때까지 1~4를 반복한다
6. 마지막 승자를 보여준다

점검: 한 문장 목표("컴퓨터와 가위바위보를 해서 먼저 2번 이기는 쪽이 승리한다")와 비교하면 빠진 것이 없고, 여섯 조각이 하는 일이 모두 다르며, 모든 조각이 읽는 즉시 시작할 수 있는 크기입니다. "정정당당한 게임이 되게 한다" 같은 말이 조각 목록에 없는 것을 눈여겨봅니다 — 마음가짐이나 목표는 조각이 아닙니다.


4스스로 풀기

난이도를 골라 아래 입력 칸에 직접 분해를 씁니다. 다 쓴 뒤 예시 답안과 비교하고, 점검 목록으로 스스로 확인합니다. 기본부터 차례로 푸는 것이 좋습니다.

문제 1 — 출석 부르기 프로그램
"선생님 대신 반 학생의 이름을 차례로 부르고, 출석했는지 결석했는지 기록해 주는 프로그램"을 분해합니다. 예제 풀이의 단계 1~3을 그대로 따라, ① 할 일 한 문장 ② 입력·처리·출력 ③ 조각 목록(5~7개, "~한다"로 끝나게)을 씁니다.

※ 입력한 내용은 저장되지 않습니다. 남기고 싶으면 공책이나 문서에 옮겨 둡니다.

예시 답안 보기 — 반드시 먼저 쓴 뒤에 엽니다

① 한 문장: 반 학생 이름을 순서대로 하나씩 보여주고, 출석/결석 입력을 받아 기록한 뒤, 마지막에 출석 결과표를 보여준다.

② 입력: 학생 명단, 출석/결석 대답  /  처리: 다음 이름 고르기, 기록하기, 명단 끝까지 반복  /  출력: 이름 표시, 결과표

1. 학생 명단을 불러온다
2. 명단에서 다음 이름을 화면에 보여준다
3. 출석/결석 입력을 받는다
4. 입력받은 결과를 기록한다
5. 명단이 끝날 때까지 2~4를 반복한다
6. 출석 결과표를 보여준다

예시와 표현이 달라도 괜찮습니다. 아래 점검 목록을 통과하는지가 기준입니다.

스스로 점검
문제 2 — 학급 문고 대출 프로그램
"우리 반 학급 문고의 책 대출과 반납을 관리하는 프로그램"을 분해합니다. 이번에는 기능이 여러 개이므로 큰 묶음(기능) → 조각의 두 단계로 나누고, 마지막에 이 프로그램이 기억해야 하는 정보(데이터) 목록을 따로 씁니다.

※ 입력한 내용은 저장되지 않습니다. 남기고 싶으면 공책이나 문서에 옮겨 둡니다.

예시 답안 보기 — 반드시 먼저 쓴 뒤에 엽니다

① 한 문장: 학급 문고의 책을 등록해 두고, 누가 어떤 책을 빌리고 반납했는지 기록하며, 현재 상태를 조회할 수 있게 한다.

[묶음 1] 책 등록 기능
  1-1. 책 제목과 관리 번호를 입력받는다
  1-2. 책 목록에 추가한다
[묶음 2] 대출 기능
  2-1. 빌리는 사람 이름과 책 번호를 입력받는다
  2-2. 그 책이 대출 가능한지 확인한다
  2-3. 대출 기록을 남기고 책 상태를 '대출 중'으로 바꾼다
[묶음 3] 반납 기능
  3-1. 반납할 책 번호를 입력받는다
  3-2. 책 상태를 '대출 가능'으로 바꾸고 반납 날짜를 기록한다
[묶음 4] 조회 기능
  4-1. 전체 책 목록과 상태를 보여준다
  4-2. 특정 사람이 빌린 책을 찾아 보여준다

③ 기억해야 하는 정보: 책 목록(제목·관리 번호·상태), 대출 기록(누가·어떤 책을·언제 빌리고 반납했는지)

묶음을 등록/대출/반납/조회로 가른 기준은 "사용자가 하려는 일"입니다. 기준이 하나로 통일되면 조각이 겹치기 어렵습니다.

스스로 점검
문제 3 — 분실물 찾기 앱 기능 나누기
"우리 학교 분실물 찾기 앱"의 기능을 3단계 깊이의 트리(큰 기능 → 작은 기능 → 바로 만들 수 있는 단위)로 나눕니다. 추가 조건 두 가지 — ① 1단계를 가른 나누기 기준(예: 사용자가 하는 일의 순서 / 화면 단위 / 다루는 정보 종류)을 함께 적을 것 ② 맨 아래 단위마다 필요한 데이터를 괄호로 적을 것.

※ 입력한 내용은 저장되지 않습니다. 남기고 싶으면 공책이나 문서에 옮겨 둡니다.

예시 답안 보기 — 반드시 먼저 쓴 뒤에 엽니다

나누기 기준: 사용자가 하는 일의 순서(주운 물건을 올린다 → 잃어버린 사람이 찾는다 → 서로 연락해 돌려받는다)

1. 주운 물건 올리기 기능
  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쪽짜리 사전에서 낱말을 찾을 때 한가운데를 펼쳐 절반을 버리는 이진탐색이 대표 사례이며, 열 번 이내에 원하는 쪽에 도달합니다.

컴퓨터가 엄청난 양의 자료를 빠르게 정렬하고 찾아내는 알고리즘 대부분이 이 전략을 씁니다.


자가진단

개념을 새 상황에 적용하는 문제입니다. 답을 고르면 즉시 채점과 해설이 나옵니다. ↻ 다시를 눌러 여러 번 풀 수 있습니다.

Q1 · 개념프로그래머가 큰 프로그램을 만들 때 가장 먼저 문제를 분해하는 이유로 가장 알맞은 것은 무엇입니까?
Q2 · 적용"단어 암기 퀴즈 프로그램"을 분해한 목록에서, 바로 만들기 시작할 수 있는 조각은 어느 것입니까?
Q3 · 점검"덧셈 연습 프로그램"을 이렇게 분해했습니다: [문제를 만든다 / 답을 입력받는다 / 채점한다 / 입력된 답이 맞는지 확인한다]. 세 기준으로 점검할 때 이 분해의 문제점은 무엇입니까?
Q4 · 판단분해를 마쳤는데 "게임 화면을 만든다"라는 조각 앞에서 여전히 무엇부터 해야 할지 막막합니다. 어떻게 해야 합니까?

핵심 정리

프로그램은 조각으로 만든다
  • 문제 분해는 큰 문제를 바로 시작할 수 있는 작은 문제로 나누는 일입니다. 코드로 옮기면 조각 하나가 함수 하나가 됩니다.
  • 분해의 순서 — ① 할 일을 한 문장으로 쓰기 ② 입력·처리·출력으로 가르기 ③ "~한다" 동작 한 개짜리 조각 목록 만들기 ④ 세 기준으로 점검하기.
  • 세 기준 — 빠짐없이 · 겹치지 않게 · 바로 시작할 수 있게. 읽어도 첫 동작이 떠오르지 않는 조각은 한 번 더 나눕니다.

이 장이 참고한 자료