문서 읽는 데 47분 · A5

A-5: 문제를 푸는 방법

목차 29
전체 7강 중 5강 · 개발 입문
난이도 · 입문

ℹ️코딩이 처음인 비전공자를 위한 첫 과목 — 컴퓨터의 원리와 “프로그래밍적 사고”를 먼저 잡아요. 선수 지식 없이 시작할 수 있어요.

안녕하세요, 홍순구 튜터입니다. 벌써 다섯 번째 시간이네요. 지난 시간(A-4)에 우리는 프로그램이 흐르는 세 가지 길(순차·선택·반복)을 배우고, 작은 프로그램 한 편을 순서도로 그리고 의사코드로 적었어요. 그리고 마지막에 표를 만들어 값을 한 줄씩 손으로 따라가 봤죠. "인기글 개수: 3"이 정말 나오는지 두 눈으로 확인하면서요. 그때 제가 "이 손으로 따라가기가 다음 시간의 주인공"이라고 약속했어요. 무한 루프를 짚으면서 "틀린 곳을 찾는 디버깅의 출발점"이라고도 했고요. 그리고 큰 문제를 작게 쪼개는 분해, 핵심만 남기는 추상화, 푸는 절차인 알고리즘도 오늘 함께 만난다고 예고했죠.

오늘 그 약속들을 한꺼번에 지킵니다. 지금까지 우리는 프로그래밍의 재료(A-3 변수·연산)와 흐름(A-4 조건·반복)을 모두 손에 넣었어요. 그런데 막상 "이 문제를 풀어 보세요" 하면 막막하죠. 재료와 흐름을 안다고 문제가 저절로 풀리는 건 아니거든요. 그 사이를 잇는 게 바로 오늘 배울 문제를 푸는 사고예요.

좋은 소식 먼저 말씀드릴게요. 오늘도 코드는 한 줄도 안 칩니다. 대신 큰 문제를 작게 쪼개고, 반복되는 모양을 찾고, 핵심만 남겨서, 푸는 절차를 짜는 네 가지 생각 도구를 배워요. 그 도구로 만든 절차를 순서도와 의사코드로 그리고, 손으로 따라가 정말 맞는지 확인하고, 틀렸으면 어디가 틀렸는지 찾아냅니다. 어렵게 들려도 괜찮아요. 사실 여러분은 일상에서 이미 이렇게 생각하고 있어요. 오늘은 그 익숙한 생각에 이름을 붙여 줄 뿐이에요.

텍스트
   오늘의 여정 — 문제를 푸는 방법

   ① 큰 문제를 작게 쪼개기 — 분해
   ② 반복되는 모양 찾기 — 패턴 인식
   ③ 핵심만 남기기 — 추상화
   ④ 문제를 푸는 절차 — 알고리즘
   ⑤ 순서도와 의사코드를 오가며 — 가장 큰 수 찾기
   ⑥ 손으로 값을 따라가기 — trace
   ⑦ 같은 문제, 다른 해법 — 효율의 직관
   ⑧ 틀린 곳 찾기 — 디버깅 사고

①에서 ④까지가 문제를 정리하는 네 가지 생각 도구예요. ⑤에서 그 정리한 문제를 순서도와 의사코드로 그리고, ⑥에서 손으로 따라가 검증합니다. ⑦에서 같은 문제의 다른 해법을 견줘 보고, ⑧에서 틀린 곳을 찾아내며 마무리해요.

💡 오늘 수업의 핵심 — "문제를 푸는 데에도 방법이 있다 — 큰 문제를 작게 쪼개고(분해), 반복되는 모양을 찾고(패턴 인식), 핵심만 남겨(추상화), 푸는 절차를 짜는 것(알고리즘)이다. 그 절차를 순서도와 의사코드로 그린 뒤 손으로 따라가(trace) 정말 맞는지 확인하고, 틀렸으면 어디서 어긋났는지 짚어 고치는 것이 디버깅이다"

🎯 학습 목표

  • 큰 문제를 분해하고, 반복되는 패턴을 찾고, 핵심만 남기는 추상화로 문제를 다룰 수 있는 크기로 정리합니다.
  • 문제를 푸는 절차인 알고리즘을 순서도와 의사코드로 그리고, 손으로 따라가기(trace)로 그 절차가 정말 맞는지 검증합니다.
  • 같은 문제에 여러 해법이 있고 효율이 다름을 직관으로 이해하고, 틀린 절차를 trace로 짚어 고치는 디버깅의 첫걸음을 뗍니다.

Step 1: "큰 문제를 작게 — 분해"

큰 문제를 만나면 누구나 막막해요. "반 전체 시험 평균을 구하세요" 같은 말을 들으면, 어디서부터 손을 대야 할지 모르겠죠. 그런데 이런 막막함을 푸는 첫 번째 도구가 있어요. 바로 분해예요. 큰 문제를 다룰 수 있는 작은 조각으로 쪼개는 거예요.

오래된 농담이 하나 있어요. "코끼리를 어떻게 먹지?" "한 번에 한 입씩." 통째로 보면 도저히 못 먹을 것 같지만, 한 입 크기로 쪼개면 결국 다 먹을 수 있어요. 문제도 똑같아요. 통째로는 막막해도, 작은 단계로 쪼개면 각 단계는 충분히 풀 만해집니다.

오늘 우리는 문제를 푸는 네 가지 생각 도구를 배우는데, 분해가 그 첫째예요. 차례로 분해·패턴 인식·추상화·알고리즘을 만나게 됩니다. 이 넷은 따로 노는 게 아니라, 문제 하나를 함께 정리하는 한 팀이에요.

"반 평균 구하기"를 분해해 볼게요. 이걸 작은 조각으로 나누면 이렇게 돼요.

텍스트
   반 평균 구하기

   ① 모든 점수를 더한다  (합계 구하기)
        └─ 첫 점수부터 끝까지 하나씩 합에 더한다
   ② 더한 값을 사람 수로 나눈다  (나누기)

막막했던 "반 평균"이 두 단계로 줄었죠. ①은 또 "하나씩 더하기"로 한 번 더 쪼갤 수 있어요. 이건 A-4에서 배운 반복으로 풀 수 있는 모양이고요. ②는 A-3에서 배운 나누기 연산 하나면 끝나요. 큰 문제가 우리가 이미 아는 작은 조각들로 분해되는 순간, 풀이가 보이기 시작합니다.

이게 분해의 힘이에요. 분해는 새로운 마법이 아니라, "큰 걸 작게 나눠 하나씩 처리한다"는 아주 자연스러운 생각이에요. 큰 청소를 방별로 나누고, 긴 여행을 날짜별로 짜듯이요. 프로그래밍에서 만나는 거의 모든 큰 문제는, 먼저 분해부터 시작합니다.

💡 한 줄 정리

분해는 막막한 큰 문제를 다룰 수 있는 작은 조각으로 쪼개는 것이며, 각 조각이 우리가 이미 아는 흐름(순차·조건·반복)이나 연산으로 풀리는 순간 전체 풀이가 보이기 시작한다.

🙋 학생 질문 — "튜터님, 어디까지 쪼개야 하나요? 끝없이 쪼갤 수 있을 것 같은데요."

아주 좋은 감각이에요. 맞아요, 마음만 먹으면 한없이 잘게 쪼갤 수 있어요. 그래서 "어디까지"가 중요한 질문이 됩니다.

기준은 간단해요. "이 조각은 이제 어떻게 풀지 바로 알겠다" 싶을 때까지만 쪼개면 돼요. 더 쪼개도 새로 보이는 게 없으면 그만두는 거죠. 예를 들어 "더한 값을 사람 수로 나눈다"는 이미 나누기 하나면 끝나니 더 쪼갤 필요가 없어요. 반대로 "모든 점수를 더한다"는 아직 "어떻게?"가 남아 있으니 "하나씩 더한다"로 한 번 더 쪼개는 게 도움이 되고요.

너무 안 쪼개면 여전히 막막하고, 너무 잘게 쪼개면 조각이 많아져 오히려 번거로워요. 그 사이 어디쯤이 적당한지는 풀다 보면 감이 잡혀요. 처음부터 완벽하게 쪼개려 애쓰지 마세요. 쪼개 보고, 막히면 더 쪼개고, 너무 잘으면 다시 묶으면 됩니다. 이 "적당함"에 대해선 오늘 마지막 생각해볼 주제에서 한 번 더 다뤄요.


Step 2: "반복되는 모양 찾기 — 패턴 인식"

문제를 분해하다 보면 신기한 일이 일어나요. "어, 이 조각 아까 그거랑 똑같은데?" 싶은 순간이 와요. 겉보기엔 다른 문제인데 속을 들여다보면 같은 모양인 거죠. 이렇게 반복되는 모양을 알아채는 게 두 번째 도구, 패턴 인식이에요.

예를 들어 볼게요. "1부터 5까지 더하기"와 "1부터 100까지 더하기"는 다른 문제처럼 보이죠. 숫자가 다르니까요. 그런데 푸는 방법은 완전히 똑같아요.

텍스트
   같은 모양, 다른 숫자

   1 부터 5 까지 더하기      1 부터 N 까지 하나씩 더한다
   1 부터 100 까지 더하기    1 부터 N 까지 하나씩 더한다
                              └ 숫자만 다르고 푸는 모양은 똑같다

둘 다 "1부터 어떤 수까지 하나씩 더한다"로 똑같아요. 5냐 100이냐는 그저 숫자만 바뀐 거죠. 그래서 5까지 더하는 법을 알면, 100까지든 만까지든 숫자만 바꿔 그대로 풀 수 있어요. 한 번 푼 모양을 재사용하는 거예요.

패턴을 알아보면 좋은 점이 분명해요. 매번 처음부터 새로 고민하지 않아도 되거든요. "이건 전에 본 그 모양이네" 하면, 그 풀이를 가져다 쓰면 끝이에요. 반 평균·동아리 평균·우리 팀 평균이 전부 "모두 더해서 인원으로 나눈다"는 같은 패턴이듯이요. 문제 겉모습은 달라도 속 모양은 같은 경우가 정말 많아요.

이 패턴 인식은 분해와 짝을 이뤄요. 분해로 문제를 작은 조각으로 쪼개 놓으면, 그 조각들 사이에서 "어, 이거 아까 그 모양" 하는 패턴이 눈에 들어오거든요. 그러면 같은 모양은 한 번만 풀어 두고 돌려쓸 수 있어요.

💡 한 줄 정리

패턴 인식은 겉모습이 다른 문제들 속에서 반복되는 같은 모양을 알아채는 것이며, 한 번 푼 모양을 재사용하면 매번 처음부터 고민하지 않아도 된다.

🙋 학생 질문 — "튜터님, 저는 그 패턴이 안 보여요. 어떻게 알아보나요?"

처음엔 당연히 안 보여요. 그게 정상이에요. 패턴 인식은 타고나는 재능이 아니라, 많이 풀어 볼수록 늘어나는 눈이거든요. 저도 처음엔 모든 문제가 다 새로워 보였어요.

비유하자면 요리와 같아요. 처음엔 레시피마다 완전히 다른 음식 같지만, 여러 번 만들다 보면 "아, 이건 볶음 계열이네", "이건 국물 내는 모양이네" 하고 큰 갈래가 보이기 시작해요. 그러면 새 레시피를 봐도 "전에 만든 그것과 비슷하네" 하고 금방 감을 잡죠. 프로그래밍의 패턴도 똑같이 쌓여요.

그러니 지금 패턴이 안 보인다고 걱정하지 마세요. 오늘은 "문제에는 반복되는 모양이 있다, 그걸 찾으면 편해진다"는 사실만 알면 충분해요. 패턴을 알아보는 눈은 앞으로 문제를 풀면 풀수록 저절로 자라납니다. 후속 언어 과목과 자료구조·알고리즘 과목에서 진짜 문제를 많이 풀면, 그 눈이 본격적으로 트여요.


Step 3: "핵심만 남기기 — 추상화"

세 번째 도구는 추상화예요. 이름이 어려워 보이지만 뜻은 간단해요. 지금 풀려는 문제에 중요한 것만 남기고, 안 중요한 곁가지는 과감히 버리는 거예요. 우리는 일상에서 이미 추상화를 쓰고 있어요. 가장 좋은 예가 지하철 노선도예요.

지하철 노선도를 떠올려 보세요. 실제 거리도, 땅의 모양도, 건물도 전부 지워져 있죠. 역과 역을 잇는 선, 그리고 갈아타는 역만 남아 있어요. 길 찾는 데 필요 없는 건 다 버린 거예요. 그래서 오히려 "어디서 갈아타면 되는지"가 한눈에 보이죠. 진짜 지도보다 노선도가 길 찾기엔 더 쓸모 있는 이유예요. 이게 추상화예요. 핵심만 남기니 문제가 또렷해지는 거죠.

문제 풀이에 적용해 볼게요. "이름들을 가나다순으로 정렬하라"는 문제가 있어요. 민지·재훈·승우를 순서대로 늘어놓는 거죠. 여기서 각 사람에 대해 우리가 아는 정보는 아주 많아요. 나이, 키, 취미, 이름의 뜻, 글자 수… 그런데 정렬에 그게 다 필요할까요?

텍스트
   이름 정렬 — 무엇이 중요하고 무엇을 버리는가

   버린다:  이름의 뜻 · 글자 수 · 한글인지 영어인지 · 나이 · 키 …
   남긴다:  "두 이름 중 누가 가나다순으로 앞에 오는가" 하나만

정렬에 필요한 건 딱 하나예요. "두 이름 중 누가 앞에 오는가." 나이도 키도 이름의 뜻도, 정렬에는 아무 상관이 없어요. 그래서 다 버리고 "순서 비교" 하나만 남기는 거예요. 곁가지를 버리고 나면 문제가 훨씬 단순해지죠. 복잡한 사람들이 아니라, 그저 "앞뒤를 비교할 수 있는 이름들"만 남으니까요.

여기서 중요한 점이 있어요. 무엇이 핵심이고 무엇이 곁가지인지는 풀려는 문제가 무엇을 묻느냐에 따라 달라져요. 같은 사람이라도, 정렬 문제에선 나이가 곁가지지만 "나이순으로 줄 세우기" 문제에선 나이가 핵심이 되죠. 추상화는 "항상 이건 버려라"가 아니라, "지금 이 문제에 무엇이 중요한가"를 묻는 거예요.

💡 한 줄 정리

추상화는 지금 풀려는 문제에 핵심만 남기고 곁가지를 버려 문제를 또렷하게 만드는 것이며, 무엇이 핵심인지는 문제가 무엇을 묻느냐에 따라 달라진다.

🙋 학생 질문 — "튜터님, 무엇을 버리고 무엇을 남길지 어떻게 정하나요? 잘못 버리면 어쩌죠?"

걱정되는 게 당연해요. 핵심을 잘못 버리면 문제를 못 풀게 되니까요. 그래서 기준이 필요해요. 기준은 하나예요. "이걸 버려도 지금 문제의 답이 똑같이 나오는가?"를 물어보면 돼요.

이름 정렬에서 나이를 지워 봐요. 나이를 몰라도 가나다순 정렬은 똑같이 나오죠? 그러니 나이는 버려도 안전해요. 반대로 "이름들 중 누가 앞에 오는가"를 지우면 정렬을 아예 할 수 없어요. 그러니 그건 핵심이라 남겨야 하고요. 이렇게 "지워도 답이 그대로면 곁가지, 지우면 못 풀면 핵심"으로 가르면 됩니다.

처음엔 헷갈려서 핵심까지 버리거나, 곁가지를 못 버리고 끌어안기도 해요. 괜찮아요. 풀다가 "어, 이 정보가 없으면 못 풀겠네" 싶으면 도로 가져오면 되고, "이건 있으나 없으나 똑같네" 싶으면 그때 버리면 돼요. 추상화도 한 번에 완벽할 필요는 없어요. 풀면서 다듬어 가는 거예요.


Step 4: "문제를 푸는 절차 — 알고리즘"

분해로 문제를 작게 쪼개고, 패턴으로 익숙한 모양을 찾고, 추상화로 핵심만 남겼어요. 이제 마지막 도구예요. 정리한 문제를 실제로 푸는 절차를 적는 거예요. 그 절차에 붙은 이름이 바로 알고리즘입니다.

알고리즘이라고 하면 뭔가 대단하고 어려운 것 같지만, 실은 여러분이 매일 쓰는 것과 똑같아요. 바로 요리 레시피예요. A-2에서 "프로그램은 명령의 순서, 곧 요리 레시피 같다"고 했던 걸 기억하시죠. 알고리즘이 딱 그거예요. "이 문제를 풀려면 이걸 먼저 하고, 그다음 이걸 하고…" 하는 정해진 순서. 라면 끓이는 절차가 라면 알고리즘이고, 반 평균 구하는 절차가 평균 알고리즘이에요.

그런데 아무 절차나 다 좋은 알고리즘은 아니에요. 좋은 알고리즘에는 세 가지 조건이 있어요.

텍스트
   좋은 알고리즘의 세 가지 조건

   ① 명확하다    누가 따라 해도 똑같이 — 모호한 말("적당히")이 없다
   ② 끝이 있다    언젠가 반드시 멈춘다 — 무한 루프가 아니다
   ③ 결과를 낸다  원하는 답이 정말로 나온다

하나씩 볼게요. 첫째, 명확해야 해요. "물을 적당히 붓고 맛있게 끓여라"는 좋은 레시피가 아니에요. "적당히"가 사람마다 다르니까요. "물 550ml를 붓고 4분간 끓여라"처럼 누가 봐도 똑같이 따라 할 수 있어야 좋은 절차예요. 컴퓨터는 특히 모호함을 못 견뎌요. A-1에서 "컴퓨터는 시킨 것만 한다"고 했죠. "적당히"를 시키면 컴퓨터는 멈춰 버려요. 무엇이 "적당히"인지 모르니까요.

둘째, 끝이 있어야 해요. 절차를 따라가다 보면 언젠가는 끝나야죠. 지난 시간에 본 무한 루프가 바로 이 조건을 어긴 거예요. 멈출 줄 모르고 영원히 도는 절차는 좋은 알고리즘이 아니에요. 셋째, 원하는 결과를 내야 해요. 끝까지 잘 돌았는데 엉뚱한 답이 나오면 소용없죠. 반 평균을 구하랬더니 합계만 내놓으면 안 되는 거예요.

이 세 조건을 떠올리면, 절차를 적을 때 스스로 점검할 수 있어요. "이거 모호한 데 없나? 끝나긴 하나? 원하는 답이 나오나?" 오늘 우리가 만들 가장 큰 수 찾기 알고리즘도, 이 세 조건을 만족하는지 보면서 짜 볼 거예요.

💡 한 줄 정리

알고리즘은 문제를 푸는 정해진 절차(요리 레시피와 같다)이며, 좋은 알고리즘은 명확하고(모호함이 없고)·끝이 있고(언젠가 멈추고)·원하는 결과를 내야 한다.

🙋 학생 질문 — "튜터님, 알고리즘이 그냥 레시피랑 같은 거면, 새로 배울 게 없는 거 아닌가요?"

날카로운 지적이에요. 맞아요, 알고리즘의 본질은 레시피와 똑같아요. 그래서 여러분은 이미 알고리즘을 짤 줄 아는 거예요. 라면을 끓이고 길을 찾는 것 자체가 절차를 따르는 일이니까요. 그 익숙함이 오히려 좋은 출발점이에요.

차이는 "누가 따라 하느냐"에 있어요. 사람은 레시피가 좀 모호해도 알아서 채워 가며 따라 해요. "소금 약간"이라고 하면 경험으로 적당히 넣죠. 그런데 컴퓨터는 그걸 못 해요. "약간"이 몇 그램인지 정확히 알려 주지 않으면 멈춰 버려요. 그래서 컴퓨터에게 줄 알고리즘은 사람용 레시피보다 훨씬 더 또박또박, 빈틈없이 적어야 해요.

그게 오늘 배우는 핵심이에요. 머릿속 절차를 "컴퓨터도 따라 할 만큼 명확하게" 적는 연습이죠. 의사코드로 적어 보는 게 바로 그 연습이에요. 사람 사이에선 통하던 모호함을, 한 단계씩 또렷하게 풀어내는 것. 그 감각을 오늘 ⑤번 Step부터 직접 길러 봅니다.


Step 5: "순서도와 의사코드를 오가며 — 가장 큰 수 찾기"

이제 네 가지 도구로 진짜 문제를 풀어 볼게요. 오늘의 주인공 문제는 가장 큰 수 찾기예요. 숫자 몇 개가 주어졌을 때 그중 제일 큰 값을 찾는 거죠. 시험 최고점, 가장 추웠던 날의 기온, 한 주 중 좋아요가 제일 많았던 글… 일상에서 "제일 큰 거 하나 골라내기"는 정말 자주 나와요.

먼저 사람은 이걸 어떻게 풀까요? 수를 죽 훑으면서 "지금까지 본 것 중 제일 큰 것"을 머릿속에 기억해 둬요. 더 큰 게 나오면 기억을 바꾸고, 아니면 그대로 두죠. 다 보고 나면 머릿속에 남은 게 답이에요. 이 생각을 절차로 옮기면 알고리즘이 됩니다.

지난 시간에 약속했죠. "A-5에서는 순서도와 의사코드를 오가며 문제를 푼다"고요. 그 약속대로, 먼저 순서도로 흐름을 그리고 그다음 의사코드로 옮겨 볼게요. 흐름이 갈라지고 되풀이되는 문제는 그림으로 먼저 보면 훨씬 또렷해요.

텍스트
   가장 큰 수 찾기 — 순서도

   ┌──────────────────┐
   │       시작       │
   └─────────┬────────┘
             │
             
   최댓값  첫 번째 수
     │
     
   ┌─ ◇ 아직 안 본 수가 있는가?
   │     ├─ 아니오 ─ 최댓값 출력  끝
   │     └─ 예
   │          
   │        ◇ 지금 수 가 최댓값 보다 큰가?
   │          ├─ 예    ─ 최댓값  지금 수
   │          └─ 아니오    (그대로 둔다)
   └──────────── 되돌아가 다음 수를 본다

흐름을 따라가 볼게요. 맨 처음 첫 번째 수를 잠정 최댓값으로 둬요. 비교하려면 기준이 하나 있어야 하니, 첫 수를 일단 "잠정 1등"으로 앉히는 거예요. 그다음 남은 수를 하나씩 보면서, 지금 보는 수가 최댓값보다 크면 최댓값을 그 수로 바꿔요. 아니면 그대로 두고요. 더 볼 수가 없으면 최댓값을 출력하고 끝납니다. 위로 되돌아가는 화살표가 보이죠? A-4에서 본 반복의 그 되돌아옴이에요.

이 순서도를 의사코드로 옮기면 이렇게 돼요. 그림으로 본 흐름을 글로 또박또박 적는 거예요.

텍스트
최댓값  첫 번째 수
나머지 수를 하나씩 보면서 반복
    만약 지금_수 가 최댓값 보다 크면
        최댓값  지금_수
최댓값 출력

나머지 수를 하나씩 보면서 반복은 A-4의 반복을 말로 푼 거예요. 남은 수가 있는 동안 한 개씩 꺼내 보겠다는 뜻이죠. 그 안에서 만약 지금_수 가 최댓값 보다 크면 최댓값을 새 값으로 바꿔요. 들여쓰기를 보면, 반복 안에 조건이 한 단계 더 들어가 있죠. A-4 마지막에 본 "반복 안에 조건" 그 모양 그대로예요.

순서도와 의사코드, 둘은 같은 알고리즘을 다르게 보여 줘요. 순서도는 흐름이 어디서 갈라지고 되돌아가는지를 그림으로, 의사코드는 그 흐름을 한 줄 한 줄 글로요. 복잡한 흐름은 순서도로 먼저 그려 보고, 또렷해지면 의사코드로 옮기는 게 편해요. 그런데 이렇게 적어 놓고 보면 한 가지 찜찜한 게 남죠. "이 절차가 정말 맞게 동작할까?" 그걸 확인하는 게 다음 Step이에요.

💡 한 줄 정리

가장 큰 수 찾기는 첫 수를 잠정 최댓값으로 두고 나머지를 하나씩 보며 더 큰 값이 나올 때마다 최댓값을 바꾸는 절차이며, 같은 알고리즘을 순서도(그림)와 의사코드(글)로 오가며 표현할 수 있다.

🙋 학생 질문 — "튜터님, 왜 굳이 첫 번째 수를 최댓값으로 시작하나요? 0으로 시작하면 안 되나요?"

정말 좋은 질문이에요. 사실 이 질문 안에 오늘 뒤에서 만날 함정이 숨어 있어요. 미리 살짝 짚어 둘게요.

비교를 하려면 비교할 기준이 하나는 있어야 해요. 아무 기준도 없이 "가장 큰 수"를 찾을 순 없거든요. 그래서 첫 번째 수를 일단 "잠정 1등"으로 앉혀 두는 거예요. 그러면 두 번째 수부터는 "지금 1등보다 큰가?"를 물어볼 수 있죠. 첫 수를 기준으로 삼는 게 가장 안전해요. 주어진 수들 안에 분명히 들어 있는 값이니까요.

0으로 시작하면 어떻게 될까요? 주어진 수가 전부 0보다 크면 우연히 답이 맞아요. 그런데 만약 수들이 전부 0보다 작다면(예: 겨울 새벽 기온 -3, -8, -1) 큰일 나요. 어떤 수도 0보다 크지 않으니 최댓값이 끝까지 0인 채로 남고, 주어진 적도 없는 0이 답으로 튀어나오죠. 바로 이게 입문자가 자주 빠지는 함정이에요. 오늘 ⑧번 Step에서 이런 틀린 절차를 손으로 따라가며 잡아내는 법을 배웁니다. 지금은 "기준은 주어진 값 중에서 잡는 게 안전하다"만 기억해 두세요.


Step 6: "손으로 값을 따라가기 — trace 본격"

의사코드를 적었으면, 이제 정말 중요한 일이 남았어요. 이 절차가 진짜 맞게 동작하는지 확인하는 거예요. 머릿속으로만 "되겠지" 하면 틀린 걸 놓치기 쉬워요. 그래서 우리는 값을 한 줄씩 손으로 따라가 봐요. 이걸 손으로 따라가기, 또는 trace라고 불러요. A-4 마지막에 살짝 맛본 그거예요. 오늘은 이걸 본격적으로 씁니다.

방법은 간단해요. 변수마다 칸을 만들고, 절차가 한 바퀴 돌 때마다 그 값이 어떻게 변하는지 표에 적는 거예요. 머릿속에서 굴리지 않고 종이에 적으니, 헷갈릴 일도 빠뜨릴 일도 없어요.

수 다섯 개가 차례로 3, 7, 2, 9, 5라고 해볼게요. Step 5의 의사코드를 따라가 볼게요. 첫 수 3을 잠정 최댓값으로 두고, 나머지 7·2·9·5를 하나씩 봅니다.

회차 보는 수 최댓값보다 큰가? 최댓값
시작 3
1 7 참 (7 > 3) 7
2 2 거짓 7
3 9 참 (9 > 7) 9
4 5 거짓 9

표를 한 줄씩 읽어 볼게요. 시작할 때 최댓값은 첫 수인 3이에요. 1회차에 7을 보니 3보다 크죠. 그래서 최댓값이 7로 바뀌어요. 2회차 2는 7보다 작으니 그대로 7. 3회차 9는 7보다 크니 9로 바뀌고, 4회차 5는 9보다 작으니 그대로 9예요. 더 볼 수가 없으니 최댓값 9를 출력하고 끝나죠. 우리가 눈으로 봐도 3·7·2·9·5 중 제일 큰 건 9가 맞아요. 절차가 제대로 동작한다는 걸 두 눈으로 확인한 거예요.

이게 trace의 힘이에요. "맞겠지"라는 짐작을 "맞다는 확인"으로 바꿔 줘요. 특히 반복이 돌 때 변수가 어떻게 변하는지는 머릿속으로 쫓기 정말 어려운데, 표로 적으면 한눈에 보여요. 알고리즘을 짰으면 곧바로 trace로 따라가 보는 습관을 들이세요. 이 습관이 다음 Step에서 틀린 곳을 찾는 결정적인 무기가 됩니다.

💡 한 줄 정리

손으로 따라가기(trace)는 변수마다 칸을 만들어 절차가 한 바퀴 돌 때마다 값의 변화를 표에 적는 것이며, "맞겠지"라는 짐작을 "맞다는 확인"으로 바꿔 준다.

🙋 학생 질문 — "튜터님, 이걸 꼭 손으로 해야 하나요? 컴퓨터한테 시키면 되잖아요."

맞아요, 나중엔 컴퓨터가 대신 돌려 줘요. 그런데 지금 우리는 아직 코드를 실행할 컴퓨터 환경이 없어요. 그건 다음 시간(A-6)에 처음 만나거든요. 그때까진 종이가 우리의 컴퓨터예요.

그리고 더 중요한 게 있어요. trace는 단순히 답을 구하려고 하는 게 아니에요. 내가 짠 절차를 내가 제대로 이해했는지 확인하는 일이에요. 컴퓨터는 답만 툭 내놓지, "왜 그 답이 나왔는지"는 설명해 주지 않아요. 그런데 손으로 따라가면, 값이 어디서 어떻게 바뀌는지가 내 머릿속에 그려져요. 그래서 틀렸을 때 "아, 여기서 어긋났구나" 하고 짚어 낼 수 있죠.

실제로 경력 많은 개발자도 까다로운 부분은 종이나 머릿속으로 trace를 해요. 컴퓨터가 있어도요. 코드를 짜기 전에, 혹은 이상하게 동작할 때, 값을 손으로 쫓아 보는 건 평생 쓰는 기술이에요. 다음 시간에 진짜 코드를 실행하게 돼도, 오늘 기른 이 눈은 계속 여러분 곁에 있을 거예요.


Step 7: "같은 문제, 다른 해법 — 효율의 직관"

재밌는 사실 하나를 말씀드릴게요. 같은 문제를 푸는 방법이 꼭 하나만 있는 건 아니에요. 답은 똑같이 나오는데, 거기 도달하는 절차가 여럿일 수 있어요. 그리고 그 절차들은 드는 노력이 서로 달라요. 가장 큰 수 찾기로 두 가지 해법을 견줘 볼게요.

텍스트
   가장 큰 수 찾기 — 두 가지 해법

   방법 A · 한 번 훑기   수를 한 번씩만 보고 가장 큰 것만 기억한다
                         수가 5개면 비교 4번, 100개면 99번
   방법 B · 줄 세우기    모든 수를 크기순으로 정렬한 뒤 맨 끝을 본다
                         줄 세우는 데 훨씬 더 많은 비교가 든다

   같은 답(9), 다른 노력 — 가장 큰 하나만 필요하면 A가 낫다

방법 A는 우리가 Step 5에서 만든 거예요. 수를 한 번씩만 죽 보면서 제일 큰 것만 기억하면 돼요. 수가 100개여도 100번만 보면 끝나죠. 방법 B는 다르게 접근해요. 모든 수를 키 순서로 줄 세운(정렬한) 다음, 맨 끝에 선 가장 큰 수를 보는 거예요. 답은 똑같이 나와요. 그런데 줄을 세우려면 수들을 서로 여러 번 비교하고 순서를 맞바꿔야 해서, 일이 훨씬 많아져요.

여기서 직관 하나가 생겨요. 가장 큰 하나만 필요한데 전부 줄 세우는 건 낭비예요. 반에서 키가 제일 큰 사람 한 명만 찾으면 되는데, 전교생을 키 순서로 다 세울 필요는 없잖아요. 한 명씩 보면서 제일 큰 사람만 기억하면 되죠. 같은 답이라도, 쓸데없이 더 많이 일하는 절차는 그만큼 느려요. 이게 효율의 직관이에요.

그런데 방법 B가 늘 나쁜 건 아니에요. 문제가 "가장 큰 수 하나"가 아니라 "이름을 가나다순으로 전부 보여 줘"라면, 그땐 줄 세우기(정렬)가 반드시 필요해요. 한 번 훑기로는 전체 순서를 만들 수 없으니까요. 결국 문제가 무엇을 원하느냐에 따라 알맞은 해법이 달라져요. 하나만 필요하면 훑기, 전체 순서가 필요하면 정렬. 좋은 프로그래머는 문제를 보고 어떤 절차가 알맞은지 고를 줄 알아요.

참고로, 절차가 얼마나 더 느린지를 정확한 잣대로 재는 도구가 따로 있어요. 흔히 "시간 복잡도"라고 부르는데, 그건 후속 자료구조·알고리즘 과목에서 본격적으로 배워요. 지금은 "쓸데없이 더 많이 일하면 느리다"는 직관 하나만 가져가면 충분합니다.

💡 한 줄 정리

같은 문제도 답에 이르는 절차가 여럿이고 드는 노력이 다르며, "필요한 것보다 더 많이 일하면 느리다"는 직관으로 문제에 알맞은 해법을 고르는 것이 효율적인 사고의 시작이다.

🙋 학생 질문 — "튜터님, 정렬이 더 느리고 일이 많으면, 그냥 안 배우면 안 되나요?"

하하, 그 마음 이해해요. 그런데 정렬은 절대 안 배우면 안 되는, 아주 중요한 절차예요. "느리다"는 건 가장 큰 수 하나만 찾을 때 이야기지, 정렬 자체가 쓸모없다는 뜻이 전혀 아니에요.

생각해 보세요. 연락처를 가나다순으로 정리하기, 검색 결과를 관련도 순으로 보여 주기, 쇼핑몰에서 가격 낮은 순으로 줄 세우기. 이 전부가 정렬이에요. 우리가 매일 쓰는 앱이 정렬 없이는 돌아가질 않아요. "전체를 순서대로 보여 줘야 하는" 문제에선 정렬이 주인공이에요.

핵심은 "정렬이 좋다 나쁘다"가 아니라 "문제에 맞는 도구를 고른다"예요. 가장 큰 하나만 필요하면 한 번 훑기로 가볍게, 전체 순서가 필요하면 정렬로. 망치가 나사에 안 맞는다고 망치가 나쁜 게 아니듯이요. 정렬을 어떻게 하는지, 어떤 정렬이 더 빠른지는 자료구조·알고리즘 과목에서 아주 재밌게 깊이 배우게 됩니다. 오늘은 "문제마다 맞는 해법이 따로 있다"는 감각만 챙기세요.


Step 8: "틀린 곳 찾기 — 디버깅 사고"

마지막 Step이에요. 오늘 우리는 절차를 짜고(알고리즘), 손으로 따라가 확인하는(trace) 법을 배웠어요. 그런데 사람이 짠 절차에는 실수가 끼기 마련이에요. 절차가 틀리면 답도 틀리죠. 이 틀린 곳을 찾아 고치는 일디버깅이라고 불러요. A-4에서 무한 루프를 보며 "디버깅의 출발점"이라고 했던 그 약속, 오늘 지킵니다.

가장 큰 수 찾기 의사코드를 다시 봐요. 그런데 이번엔 누군가 한 글자를 잘못 적었어요. 어디가 틀렸는지 한눈에 보이나요?

텍스트
최댓값  첫 번째 수
나머지 수를 하나씩 보면서 반복
    만약 지금_수 가 최댓값 보다 작으면      여기를 잘못 적었다
        최댓값  지금_수
최댓값 출력

보다 크면이어야 할 곳에 보다 작으면이라고 적혀 있어요. 부등호 방향을 거꾸로 쓴 거죠. 딱 한 글자 차이예요. 그런데 이 한 글자가 절차를 완전히 망가뜨려요. 눈으로만 보면 "그럴듯한데?" 싶을 수도 있어요. 그래서 우리에겐 trace가 있는 거예요. 손으로 따라가면 틀린 게 드러납니다. 같은 수 3, 7, 2, 9, 5로 따라가 볼게요.

회차 보는 수 최댓값보다 작은가? 최댓값
시작 3
1 7 거짓 3
2 2 참 (2 < 3) 2
3 9 거짓 2
4 5 거짓 2

뭔가 이상하죠? 가장 큰 수를 찾는다면서 최댓값이 3에서 2로 오히려 작아졌어요. 2회차에서 2가 3보다 작은데도 최댓값을 2로 바꿔 버린 거예요. 결국 출력되는 값은 2. 그런데 3·7·2·9·5 중 가장 큰 건 9잖아요. 답이 완전히 틀렸어요. 오히려 가장 작은 수가 나와 버렸죠.

바로 이 순간이 디버깅의 핵심이에요. trace 표에서 "최댓값이 커져야 하는데 작아지는" 그 이상한 줄을 발견하면, "여기서 뭔가 잘못됐다"는 걸 알 수 있어요. 그 줄을 만든 의사코드를 거슬러 보면 보다 작으면이 눈에 들어오죠. 보다 크면으로 고치면 절차가 제대로 돌아와요. 이렇게 trace로 이상한 곳을 짚고, 그 줄을 거슬러 올라가 원인을 고치는 게 디버깅이에요.

디버깅에서 가장 중요한 마음가짐을 하나 말씀드릴게요. 틀리는 건 부끄러운 게 아니에요. 아무리 뛰어난 개발자도 실수하고, 그래서 매일 디버깅을 해요. 중요한 건 틀리지 않는 게 아니라, 틀렸을 때 차분히 따라가며 찾아내는 능력이에요. 오늘 trace로 한 글자 버그를 잡아낸 그 과정이, 앞으로 여러분이 평생 쓸 디버깅의 첫걸음이에요.

💡 한 줄 정리

디버깅은 틀린 절차를 trace로 따라가 "값이 이상해지는 줄"을 짚고, 그 줄을 거슬러 올라가 원인(예: 부등호 방향)을 고치는 일이며, 틀리는 것은 부끄러운 게 아니라 차분히 찾아 고치면 되는 일상이다.

🙋 학생 질문 — "튜터님, 그냥 처음부터 안 틀리게 잘 짜면 디버깅이 필요 없는 거 아닌가요?"

이상적으로는 그렇죠. 그런데 현실에선 누구도 처음부터 완벽하게 짜지 못해요. 정말 누구도요. 수십 년 경력의 개발자도 코드를 짜면 거의 항상 어딘가 틀려 있어요. 그게 사람이 일하는 방식이에요. 그러니 "안 틀리게 짜기"를 목표로 삼으면 오히려 좌절하기 쉬워요.

더 현실적인 목표는 "틀려도 빨리 찾아 고치기"예요. 그래서 좋은 개발자와 그렇지 않은 개발자의 차이는 "실수를 하느냐"가 아니라 "실수를 얼마나 잘 찾아내느냐"에 있어요. 오늘 배운 trace가 바로 그 무기예요. 차분히 한 줄씩 따라가면, 아무리 교묘하게 숨은 버그도 결국 드러나거든요.

그리고 좋은 소식이 있어요. 다음 시간(A-6)엔 우리를 도와주는 친구가 생겨요. 컴퓨터가 "여기 뭔가 이상해요" 하고 빨간 줄로 알려 주는 에러 메시지예요. 처음엔 빨간 줄이 무섭게 보이지만, 사실은 "여기를 보라"고 알려 주는 고마운 친구예요. 종이에서 손으로 버그를 찾던 오늘의 눈에, 다음 시간엔 컴퓨터의 도움까지 더해지는 거죠.


마무리

다섯 번째 시간, 정말 잘 따라오셨어요. 오늘 우리는 코드 한 줄 없이도, 막막한 문제를 푸는 사고의 도구들을 손에 넣었어요. 큰 문제를 작게 쪼개고(분해), 같은 모양을 찾고(패턴), 핵심만 남기고(추상화), 푸는 절차를 짰죠(알고리즘). 그 절차를 순서도와 의사코드로 그리고, 손으로 따라가 맞는지 확인하고, 틀린 곳까지 찾아냈어요. 지금까지 모은 재료와 흐름이, 오늘 비로소 "문제를 푸는 힘"으로 모였습니다.

오늘 배운 핵심 세 가지

  1. 💡 문제를 푸는 데에도 도구가 있다. 큰 문제를 작게 쪼개는 분해, 반복되는 모양을 찾는 패턴 인식, 핵심만 남기는 추상화, 푸는 절차를 짜는 알고리즘. 이 넷으로 막막한 문제를 다룰 수 있는 크기로 정리한다.
  2. 💡 절차는 그린 뒤 반드시 따라가 확인한다. 알고리즘을 순서도(그림)와 의사코드(글)로 표현하고, 손으로 따라가기(trace)로 값을 쫓으면 "맞겠지"라는 짐작이 "맞다는 확인"으로 바뀐다.
  3. 💡 같은 문제도 해법이 여럿이고, 틀리면 찾아 고치면 된다. 필요한 것보다 더 많이 일하면 느리다는 효율의 직관으로 해법을 고르고, 틀렸을 땐 trace로 이상한 줄을 짚어 원인을 고치는 디버깅으로 바로잡는다.

다음 시간 예고

오늘까지 우리는 모든 사고를 종이 위에서 다뤘어요. 의사코드도, 순서도도, trace도 전부 손으로 그렸죠. 다음 시간(A-6)에는 드디어 종이를 떠나 진짜 컴퓨터로 갑니다. 파일과 폴더가 무엇인지, 코드를 적는 에디터와 명령을 내리는 터미널이 무엇인지 처음 만나고, 설치도 계정도 없이 브라우저만으로 진짜 코드 한 줄을 직접 실행해 봐요. "화면에 글자를 띄우는" 그 한 줄이, 여러분이 짠 절차가 처음으로 살아 움직이는 순간이 될 거예요.

그리고 오늘 우리가 종이에서 손으로 틀린 곳을 찾았다면, 다음 시간엔 컴퓨터가 빨간 줄로 "여기 틀렸어요"라고 알려 주는 에러를 처음 만나요. 빨간 줄은 무서운 게 아니라, 어디를 보라고 알려 주는 친구예요. 오늘 기른 디버깅의 눈에 컴퓨터의 도움까지 더해지는, 설레는 시간이 기다리고 있어요.


과제

오늘도 종이와 연필로 하는 연습이에요. 문제를 푸는 사고는 직접 쪼개 보고, 직접 따라가 봐야 늘어요. 틀려도 좋으니 부담 없이 손을 움직여 보세요. 그게 오늘 배운 모든 것의 핵심입니다.

[기초] 일상의 큰 일 하나를 분해 트리로 그리기

일상에서 손이 많이 가는 일 하나를 골라(예: 생일 파티 준비·일주일 여행 짐 싸기·방 대청소), 그걸 분해 트리로 그려 보세요. 큰 일을 먼저 3~5개의 작은 단계로 나누고, 그중 아직 막막한 단계가 있으면 한 번 더 작게 쪼개면 됩니다. Step 1의 "반 평균 구하기" 트리를 본보기로 삼으세요. 다 그렸으면 스스로 물어보세요. "각 조각이 이제 어떻게 할지 바로 알겠는가?" 그렇다면 잘 분해된 거예요. 정답은 없어요. 같은 일도 사람마다 다르게 쪼갤 수 있습니다.

[응용] 반 평균 구하기를 의사코드로 적고 손으로 따라가기

다섯 명의 시험 점수로 반 평균을 구하는 의사코드를 직접 적어 보세요. Step 1에서 본 분해를 떠올리면 됩니다. 먼저 합계를 0으로 두고(합계 ← 0), 다섯 점수를 하나씩 더한 뒤(합계 ← 합계 + 점수), 마지막에 사람 수로 나누면(평균 ← 합계 ÷ 5) 돼요. 다 적었으면 점수 예시(예: 80, 90, 70, 100, 60)로 trace 표를 채워, 합계가 한 줄씩 어떻게 쌓이고 마지막에 평균이 얼마로 나오는지 손으로 확인해 보세요. 표의 칸은 회차·더하는 점수·합계 정도면 충분합니다.

[심화] 일부러 틀린 의사코드의 버그를 trace로 잡아내기

아래는 "가장 작은 수 찾기" 의사코드인데, 한 군데가 틀려 있어요. 수 3, 7, 2, 9, 5로 trace 표를 채워 어떤 값이 출력되는지 확인하고, 어디가 왜 틀렸는지 짚어 고쳐 보세요. (힌트: Step 8에서 했던 것처럼, 최솟값이 이상하게 변하는 줄을 찾으면 됩니다.)

텍스트
최솟값  첫 번째 수
나머지 수를 하나씩 보면서 반복
    만약 지금_수 가 최솟값 보다 크면
        최솟값  지금_수
최솟값 출력

다 풀었으면 한 걸음 더 가 보세요. 만약 첫 줄을 최솟값 ← 0으로 바꾸면 어떤 문제가 생길까요? 수가 전부 0보다 큰 경우와, 전부 0보다 작은 경우를 각각 떠올려 보면 Step 5의 학생 질문에서 짚었던 함정이 보일 거예요.


생각해볼 주제

정답이 하나로 떨어지지 않는 질문들이에요. 혼자 곰곰이 생각해도 좋고, 같이 공부하는 사람과 이야기 나눠도 좋습니다.

1. 문제를 어디까지 쪼개야 적당할까?

Step 1에서 분해를 배우며 "이제 어떻게 풀지 알겠다 싶을 때까지 쪼갠다"고 했어요. 그런데 그 "적당함"이 늘 분명하진 않죠. 너무 안 쪼개면 여전히 막막하고, 너무 잘게 쪼개면 조각이 너무 많아져 오히려 헷갈려요. 여러분은 무엇을 기준으로 "이만하면 됐다"를 판단할 것 같나요? 요리·청소·여행 준비처럼 익숙한 일을 떠올리며, 자신만의 "적당한 조각 크기" 기준을 정리해 보세요.

2. 같은 답을 내는 두 절차 중, 무엇이 더 좋은 절차일까?

Step 7에서 가장 큰 수 찾기의 두 해법을 봤어요. 답은 같아도 노력이 달랐죠. 그런데 "좋은 절차"의 기준이 빠름 하나뿐일까요? 빨리 도는 절차, 읽고 이해하기 쉬운 절차, 나중에 고치기 쉬운 절차 중 무엇을 더 중요하게 볼지는 상황마다 다를 수 있어요. 빠르지만 알아보기 힘든 절차와, 조금 느려도 한눈에 이해되는 절차가 있다면 여러분은 어느 쪽을 고를 건가요? 그리고 그 선택이 달라지는 상황은 언제일까요?

3. 컴퓨터는 왜 스스로 "이 답은 틀렸어"라고 못 알아챌까?

Step 8에서 우리는 trace로 틀린 곳을 찾았어요. 그런데 가만 보면, 정작 그 틀린 절차를 돌린 컴퓨터는 "최솟값을 구하랬는데 최댓값을 내놓았다"는 걸 전혀 몰라요. 시킨 대로 충실히 2를 출력했을 뿐이죠. 왜 컴퓨터는 자기가 낸 답이 틀렸다는 걸 스스로 알아채지 못할까요? A-1에서 배운 "컴퓨터는 시킨 것만 한다"와 연결해서 생각해 보세요. 그리고 그렇다면 "맞는지 틀린지 판단하는 일"은 누구의 몫일지도요. 이 질문에 답해 보면, 왜 디버깅이 사람의 일인지가 또렷해질 거예요.

✅ 예시 답안정답 보기

이 문서는 A-5 「문제를 푸는 방법」의 과제와 생각해볼 주제에 대한 예시답안입니다. 정답을 외우는 용도가 아니라, 문제를 어떻게 분해하고·절차로 짜고·손으로 따라가 확인하는지 그 흐름을 참고하는 용도로 보세요. 이 과목은 "정답"보다 "스스로 쪼개고 따라가 보는 것"이 더 중요합니다. 분해 방식이 저와 달라도, 각 조각이 풀 만하게 쪼개졌다면 충분합니다.


과제 예시답안

🎯 [과제 1 예시답안] 일상의 큰 일 하나를 분해 트리로 그리기

채점 포인트

항목 배점 기준
큰 일을 작은 단계로 40% 큰 일을 3~5개의 작은 단계로 나눴는가
막막한 단계 더 쪼개기 30% 아직 막막한 단계를 한 번 더 작게 쪼갰는가
조각의 적정성 30% 각 조각이 "이제 어떻게 할지 바로 아는" 크기인가

풀이 예시

"생일 파티 준비"를 골랐습니다.

텍스트
   생일 파티 준비

   ① 초대하기
        └─ 올 사람 정하기  연락 돌리기
   ② 먹을 것 준비하기
        └─ 메뉴 정하기  장 보기  만들기
   ③ 공간 꾸미기
        └─ 풍선·현수막 사기  달기
   ④ 당일 진행하기

막막했던 "생일 파티 준비"가 네 단계로 줄었습니다. ①·②·③은 아직 "어떻게?"가 남아 있어 한 번 더 쪼갰고, ④는 당일에 하면 되니 더 쪼개지 않았습니다.

💡 튜터의 한마디 — 아주 잘 쪼갰어요. 이 과제의 핵심은 "큰 일을 통째로 보면 막막한데, 작게 나누면 각 단계는 할 만해진다"는 분해의 감각을 직접 느껴 보는 거예요. 특히 ②번 "먹을 것 준비"를 메뉴 정하기·장 보기·만들기로 한 번 더 쪼갠 게 좋아요. "장 보기"는 이제 바로 할 수 있으니 더 안 쪼개도 되죠. 이렇게 "이제 어떻게 할지 알겠다" 싶은 데서 멈추는 감각이 정확합니다. 정답이 따로 있는 게 아니에요. 같은 파티도 사람마다 다르게 쪼갤 수 있고, 다 맞아요. 중요한 건 통째의 막막함이 "할 만한 조각들"로 바뀌었다는 것뿐이에요.

🎯 [과제 2 예시답안] 반 평균 구하기를 의사코드로 적고 손으로 따라가기

채점 포인트

항목 배점 기준
분해와 합계 누적 35% 합계를 0에서 시작해 점수를 하나씩 더했는가
평균 계산 30% 모두 더한 합계를 사람 수로 나눴는가
손으로 따라가기 35% trace 표로 합계가 쌓이는 과정과 평균을 확인했는가

풀이 예시

Step 1의 분해(① 모두 더하기 → ② 사람 수로 나누기)를 그대로 의사코드로 옮겼습니다. 점수는 80, 90, 70, 100, 60으로 했습니다.

텍스트
합계  0
다섯 점수를 하나씩 보면서 반복
    합계  합계 + 지금_점수
평균  합계 ÷ 5
평균 출력

합계를 0에서 시작해 점수를 하나씩 더하고, 마지막에 사람 수 5로 나눴습니다. 값을 표로 따라가 볼게요.

회차 더하는 점수 합계
시작 0
1 80 80
2 90 170
3 70 240
4 100 340
5 60 400

다섯 점수를 다 더하니 합계가 400이 됐어요. 이제 사람 수 5로 나누면 400 ÷ 5 = 80. 평균은 80점입니다.

💡 튜터의 한마디 — 깔끔하게 잘 풀었어요. 이 과제의 진짜 목적은 두 가지예요. 첫째, Step 1에서 배운 분해를 실제 의사코드로 옮겨 본 것. "반 평균"이라는 큰 문제가 "더하기 반복 + 나누기 한 번"으로 쪼개져 풀린 거죠. 둘째, 합계가 0에서 시작해 80, 170, 240… 으로 한 줄씩 쌓이는 걸 trace 표로 두 눈으로 확인한 거예요. 특히 합계 ← 0으로 시작하는 게 중요해요. 만약 시작값을 안 정해 두면 첫 점수를 어디에 더할지 알 수 없거든요. 더하기 전에 그릇(합계)을 0으로 비워 두는 이 습관은 앞으로도 자주 만나게 됩니다.

🎯 [과제 3 예시답안] 일부러 틀린 의사코드의 버그를 trace로 잡아내기

채점 포인트

항목 배점 기준
trace로 출력값 확인 35% 표를 채워 엉뚱한 값(9)이 출력됨을 확인했는가
버그 위치 짚기 40% 부등호 방향(크면작으면)이 틀렸음을 찾았는가
고치기와 0 시작 함정 25% 올바로 고치고, 최솟값 ← 0의 위험을 설명했는가

풀이 예시

주어진 "가장 작은 수 찾기" 의사코드를 수 3, 7, 2, 9, 5로 따라가 봤습니다. 첫 수 3을 잠정 최솟값으로 두고 나머지를 봅니다.

회차 보는 수 최솟값보다 큰가? 최솟값
시작 3
1 7 참 (7 > 3) 7
2 2 거짓 7
3 9 참 (9 > 7) 9
4 5 거짓 9

출력값은 9가 나왔어요. 그런데 3·7·2·9·5 중 가장 작은 수는 2여야 하죠. 최솟값을 찾는다면서 오히려 가장 큰 수가 나와 버렸어요. 표를 보면 1회차부터 최솟값이 3에서 7로 커졌어요. 가장 작은 값을 찾는데 값이 커지는 건 말이 안 되죠. 여기서 뭔가 틀렸다는 걸 알 수 있어요.

틀린 곳은 조건 줄이에요.

텍스트
    만약 지금_수 가 최솟값 보다 크면      여기가 틀렸다

가장 작은 수를 찾으려면 "지금 수가 최솟값보다 작을 때" 갱신해야 하는데, 보다 크면으로 거꾸로 적혀 있었어요. 보다 작으면으로 고치면 됩니다.

텍스트
최솟값  첫 번째 수
나머지 수를 하나씩 보면서 반복
    만약 지금_수 가 최솟값 보다 작으면
        최솟값  지금_수
최솟값 출력

고친 의사코드로 다시 따라가면, 2회차에서 2가 3보다 작아 최솟값이 2로 바뀌고, 끝까지 2로 남아 정답 2가 출력됩니다.

한 걸음 더 — 만약 첫 줄을 최솟값 ← 0으로 바꾸면 어떻게 될까요? 수가 전부 0보다 크면(예: 80, 90, 70) 어떤 수도 0보다 작지 않으니 최솟값이 끝까지 0에 머물러요. 주어진 적도 없는 0이 답으로 나오죠. 반대로 수가 전부 0보다 작아도 0이 곁다리로 끼어들 위험이 있고요. 그래서 기준은 항상 주어진 값 중에서(첫 번째 수로) 잡는 게 안전해요. Step 5의 학생 질문에서 짚었던 함정이 바로 이거예요.

💡 튜터의 한마디 — 정확하게 잡아냈어요. 이 과제의 핵심은 "눈으로만 보면 그럴듯한 버그도, trace로 따라가면 드러난다"는 거예요. 부등호 한 글자가 거꾸로 됐을 뿐인데 결과가 완전히 뒤집혔죠. 표에서 "작은 값을 찾는데 값이 커지는" 이상한 줄을 발견한 게 디버깅의 결정적 순간이에요. 그 이상함을 단서로 조건 줄을 거슬러 올라가 원인을 찾았고요. 0으로 시작할 때의 위험까지 짚어 본 건 정말 훌륭해요. 이게 Step 5의 "기준은 주어진 값에서 잡는다"와 정확히 이어지거든요. 틀린 걸 찾아 고치는 이 과정 전체가 바로 디버깅이고, 오늘 여러분은 그걸 직접 해냈어요.


생각해볼 주제 예시답안

🤔 [생각해볼 주제 1] 문제를 어디까지 쪼개야 적당할까

문제 상황 요약

Step 1에서 분해를 배우며 "이제 어떻게 풀지 알겠다 싶을 때까지 쪼갠다"고 했다. 그런데 그 "적당함"이 늘 분명하진 않다. 너무 안 쪼개면 막막하고, 너무 잘게 쪼개면 조각이 많아 헷갈린다. 무엇을 기준으로 "이만하면 됐다"를 판단할지 자기만의 기준을 정리해 보는 주제다.

튜터의 가이드 및 해설

먼저 양 극단을 떠올려 보자. 한쪽 끝은 "전혀 안 쪼갬"이다. "생일 파티 준비"를 통째로 두면 어디서 손대야 할지 막막하다. 반대쪽 끝은 "끝없이 쪼갬"이다. "장 보기"를 "집을 나선다 → 신발을 신는다 → 문을 연다…"까지 쪼개면, 조각이 너무 잘아 오히려 전체가 안 보인다. 적당함은 이 둘 사이 어딘가에 있다.

기준을 한 문장으로 잡으면 이렇다. "이 조각은 이제 별 고민 없이 바로 할 수 있다" 싶으면 거기서 멈춘다. "장 보기"는 대부분의 사람에게 이미 할 만한 일이라 더 안 쪼개도 된다. 반면 "먹을 것 준비"는 아직 "뭘 어떻게?"가 남아 있으니 메뉴 정하기·장 보기·만들기로 한 번 더 쪼개는 게 도움이 된다. 즉 "막막함이 남아 있으면 더 쪼개고, 막막함이 사라지면 멈춘다"가 기준이다.

그런데 이 기준에는 재밌는 점이 있다. "할 만한 크기"가 사람마다 다르다는 거다. 요리에 익숙한 사람은 "저녁 차리기"를 더 안 쪼개도 되지만, 처음 하는 사람은 더 잘게 쪼개야 안심이 된다. 그래서 정답인 분해는 없다. 같은 문제도 푸는 사람의 경험에 따라 알맞은 조각 크기가 달라진다. 프로그래밍도 똑같다. 익숙한 기능은 큰 덩어리로 두고, 낯선 기능은 더 잘게 쪼개 가며 푼다.

마지막으로, 분해는 한 번에 완벽할 필요가 없다. 일단 쪼개 보고, 풀다가 막히면 그 조각을 더 쪼개고, 너무 잘아 번거로우면 다시 묶으면 된다. 분해는 "처음에 완벽히 설계하는 일"이 아니라 "풀면서 다듬어 가는 일"에 가깝다.

💡 핵심을 한마디로

"이 조각은 이제 바로 할 수 있다" 싶으면 멈추고, 아직 막막하면 더 쪼갠다. 할 만한 크기는 푸는 사람의 경험에 따라 다르므로 정답인 분해는 없으며, 풀면서 더 쪼개거나 다시 묶어 가며 다듬으면 된다.

🤔 [생각해볼 주제 2] 같은 답을 내는 두 절차 중, 무엇이 더 좋은 절차일까

문제 상황 요약

Step 7에서 가장 큰 수 찾기의 두 해법을 봤다. 답은 같아도 드는 노력이 달랐다. 그런데 "좋은 절차"의 기준이 빠름 하나뿐일까? 빨리 도는 절차, 읽고 이해하기 쉬운 절차, 나중에 고치기 쉬운 절차 중 무엇을 우선할지는 상황마다 다를 수 있다. 자기 나름의 기준을 세워 보는 주제다.

튜터의 가이드 및 해설

가장 먼저 떠오르는 기준은 "빠름"이다. Step 7에서 본 대로, 같은 답이라도 쓸데없이 더 많이 일하는 절차는 느리다. 가장 큰 하나만 필요한데 전부 줄 세우는 건 낭비였다. 그래서 "필요한 만큼만 일하는" 절차가 좋은 절차의 한 조건인 건 분명하다.

그런데 빠름이 전부는 아니다. 두 번째 기준은 "읽고 이해하기 쉬운가"다. 아무리 빠른 절차라도, 무슨 일을 하는지 한눈에 안 들어오면 문제가 생긴다. 나중에 그 절차를 다시 볼 사람(또는 미래의 나)이 한참을 들여다봐야 겨우 이해한다면, 그 시간도 비용이다. 조금 느려도 흐름이 또렷한 절차가, 빠르지만 알아보기 힘든 절차보다 나을 때가 많다.

세 번째 기준은 "고치기 쉬운가"다. 프로그램은 한 번 짜고 끝나지 않는다. 계속 고치고 늘려 간다. 그래서 "여기 하나만 바꾸면 되는" 절차가, "여러 군데를 다 바꿔야 하는" 절차보다 좋다. 지난 시간 무한 루프 이야기에서 "복사해 붙이면 고칠 때 지옥을 본다"고 했던 게 이 이야기다.

그렇다면 셋 중 무엇을 우선할까? 상황에 따라 다르다. 수백만 명이 동시에 쓰는 서비스의 핵심 부분이라면 빠름이 중요하다. 작은 도구나 한 번 쓰고 말 코드라면, 빠름보다 "빨리 짜고 쉽게 이해되는" 게 낫다. 여럿이 함께 오래 고쳐 갈 코드라면 "읽고 고치기 쉬움"이 가장 중요하다. 그래서 좋은 프로그래머는 "무조건 빠르게"가 아니라 "이 상황에서 무엇이 가장 중요한가"를 먼저 묻는다.

입문 단계에서 꼭 가져갈 한 가지는 이거다. 처음엔 빠름보다 "또렷함"을 우선하자. 빠르지만 알아볼 수 없는 절차보다, 조금 느려도 내가 이해하고 고칠 수 있는 절차가 입문자에겐 백배 낫다. 빠르게 만드는 기술은 나중에 자료구조·알고리즘 과목에서 충분히 배운다. 지금은 "내가 읽고 설명할 수 있는 절차"를 짜는 게 먼저다.

💡 핵심을 한마디로

좋은 절차의 기준은 빠름 하나가 아니라 빠름·읽기 쉬움·고치기 쉬움 셋이며, 무엇을 우선할지는 상황에 따라 다르다. 입문 단계에서는 빠름보다 "내가 읽고 고칠 수 있는 또렷함"을 먼저 챙기는 게 낫다.

🤔 [생각해볼 주제 3] 컴퓨터는 왜 스스로 "이 답은 틀렸어"라고 못 알아챌까

문제 상황 요약

Step 8에서 trace로 틀린 곳을 찾았다. 그런데 정작 그 틀린 절차를 돌린 컴퓨터는 "최솟값을 구하랬는데 최댓값을 내놓았다"는 걸 전혀 몰랐다. 시킨 대로 충실히 답을 냈을 뿐이다. 왜 컴퓨터는 자기가 낸 답이 틀렸음을 스스로 알아채지 못할까? A-1의 "컴퓨터는 시킨 것만 한다"와 연결해, 맞고 틀림을 판단하는 일이 누구의 몫인지 생각해 보는 주제다.

튜터의 가이드 및 해설

핵심은 첫 시간에 배운 한 문장에 있다. 컴퓨터는 시킨 것만 정확히 한다. Step 8의 틀린 절차는 "지금 수가 최솟값보다 크면 바꿔라"였다. 컴퓨터는 이걸 글자 그대로, 한 치의 어김도 없이 수행했다. 그래서 9를 출력했다. 컴퓨터 입장에선 아무 잘못이 없다. 시킨 일을 완벽하게 해냈으니까.

문제는 컴퓨터가 "이 절차의 목적"을 모른다는 데 있다. 우리는 "가장 작은 수를 찾고 싶다"는 목적을 머릿속에 갖고 있다. 그래서 9가 나오면 "어, 이건 가장 작은 게 아니잖아" 하고 안다. 그런데 컴퓨터에겐 그 목적이 없다. 컴퓨터가 받은 건 "이렇게 해라"라는 절차뿐이지, "이런 답이 나와야 한다"는 목적이 아니다. 절차와 결과만 있고, "그 결과가 원하던 것인지"를 견줄 잣대가 컴퓨터 안엔 없는 것이다.

비유하자면 이렇다. 누군가에게 "왼쪽으로 가라"고 길을 알려 줬는데 사실은 오른쪽이 맞았다고 하자. 그 사람이 충실히 왼쪽으로 갔다면, 그를 탓할 순 없다. 시킨 대로 했으니까. 틀린 건 길을 알려 준 사람이다. 컴퓨터도 똑같다. 틀린 절차를 충실히 따른 컴퓨터가 아니라, 절차를 잘못 적은 사람에게 책임이 있다.

그래서 "맞는지 틀린지 판단하는 일"은 사람의 몫이다. 컴퓨터는 무엇이 옳은 답인지 모른 채 시킨 대로만 하므로, 그 답이 목적에 맞는지 확인하는 건 절차를 적은 사람이 해야 한다. 바로 이것이 디버깅이 사람의 일인 이유다. 오늘 우리가 trace로 "이 답은 틀렸다"를 알아챈 건, 컴퓨터가 못 하는 "목적과 결과를 견주는 일"을 사람이 대신 해 준 것이다. 컴퓨터의 성실함은 강력하지만, 그 성실함에 옳은 방향을 정해 주는 건 끝내 사람이다.

💡 핵심을 한마디로

컴퓨터는 절차의 "목적"을 모른 채 시킨 대로만 정확히 하므로, 자기 답이 틀렸는지 견줄 잣대가 없다. 목적과 결과를 견주어 맞고 틀림을 판단하는 일은 사람의 몫이며, 그래서 디버깅은 끝내 사람의 일이다.

전체 목록 개발 입문