5단원 '반복'의 여섯 레슨에서 9문제를 내고, 1~4단원에서 3문제를 섞었습니다. 앞 단원 문제가 어느 레슨인지는 정답을 펼치면 보입니다. 출력을 쓰는 문제는 빈칸과 줄바꿈까지 종이에 끝까지 쓴 뒤 정답을 펼치세요. 줄 수를 알려 주지 않는 문제는 마지막 줄까지 다 씁니다. 막히면 정답 앞의 힌트를 먼저 펼칩니다. 점수는 매기지 않습니다.
한 번에 다 풀 필요는 없습니다. 문제 1~10은 폰으로도 풀 수 있고(약 30~40분), 끝의 만들어 보기 둘은 컴퓨터에서 Node로 직접 돌려 봅니다. 이 단원을 건너뛰어도 되는지 보려면 문제 1 · 3 · 4 · 6 · 8 · 9 여섯을 먼저 풀어 보세요(약 15분). 건너뛸지 볼 때는 힌트를 펴지 않고 풉니다. 힌트를 펴고 맞힌 문제나 짐작으로 고른 문제는 틀린 것으로 치고 그 레슨을 봅니다. 모두 맞으면 이 단원 레슨은 건너뛰고, 틀린 문제가 있으면 그 정답 끝의 레슨만 봅니다. 파이썬을 배웠다면 파이썬과 달라지는 곳이 이 여섯에 들어 있습니다(정답의 '파이썬에서는' 줄). 끝의 만들어 보기 둘은 골라서 풉니다.
끝의 두 문제는 프로그램을 직접 만들어 봅니다. 컴퓨터가 있으면 저장해 돌려 맞춰 보고, 폰으로만 본다면 문제에 적힌 값으로 내 코드를 한 줄씩 따라가 나와야 할 화면과 맞춰 봅니다. 실행 결과는 모두 Node 26으로 돌린 것입니다.
문제 1
카페 주전자에 물을 데웁니다. 1분마다 30도씩 오르고, 100도가 안 되는 동안 데웁니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요.
let temp = 20;
while (temp < 100) {
temp = temp + 30;
console.log(`${temp}도`);
}
힌트
추적 표(줄 · 바뀐 이름 · 값 · 출력)를 한 줄씩 채우며 따라가 보세요.
힌트 둘
2번 줄의 조건을 언제 보는지, 추적 표로 한 줄씩 따라가 보세요.
정답
모두 세 줄입니다.
50도
80도
110도추적 표로 따라가면 이렇습니다.
| 줄 | 바뀐 이름 | 값 | 출력 |
|---|---|---|---|
| 1 | temp | 20 | |
| 2 | 조건 temp < 100 | true | |
| 3 | temp | 50 | |
| 4 | 50도 | ||
| 2 | 조건 temp < 100 | true | |
| 3 | temp | 80 | |
| 4 | 80도 | ||
| 2 | 조건 temp < 100 | true | |
| 3 | temp | 110 | |
| 4 | 110도 | ||
| 2 | 조건 temp < 100 | false |
셋째 바퀴의 3번 줄에서 temp가 110에 붙어 조건이 거짓이 되어도, 그 바퀴는 4번 줄까지 마저 실행해 110도를 찍습니다.
흔한 오답은 110도를 빼고 두 줄만 쓰는 것입니다. 100도를 넘는 순간 반복이 멈춘다고 본 것입니다(조건을 늘 지켜본다는 생각). 조건은 덩어리를 시작할 때(2번 줄)만 봅니다(규칙 4).
다시 볼 레슨: while과 추적 표
문제 2
남은 쿠키를 하나씩 내주며 남은 수를 찍으려 합니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요.
let left = 3;
while (left = 0) {
console.log('남음', left);
left = left - 1;
}
console.log('끝', left);
힌트
2번 줄의 조건 자리에 등호가 몇 개인지 보세요.
정답
모두 한 줄입니다.
끝 0- 2번 줄: 등호 하나는 묻지 않고 left를 0에 다시 붙입니다. 그 값 0이 조건이 되고, 0은 거짓 같은 값이라 덩어리를 한 번도 실행하지 않습니다.
- 6번 줄: left는 2번 줄에서 0에 붙었으니
끝 0을 찍습니다.
흔한 오답은 끝 3입니다. 2번 줄이 left가 0과 같은지 묻기만 한다고 본 것입니다(등호 하나로 같은지 묻는다는 생각). 등호 하나는 조건 자리에서도 이름을 다시 붙입니다(규칙 2). 남음 3 · 남음 2 · 남음 1 · 끝 0을 쓰면 쓴 코드 대신 뜻한 코드(left > 0)를 따라간 것입니다.
문제 3
영어 낱말 'sea'의 글자를 번호와 함께 찍으려 합니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요.
const word = 'sea';
const n = word.length;
for (let i = 1; i <= n; i++) {
console.log(i, word[i]);
}
힌트
'sea'의 글자마다 자리 번호를 0부터 적고, i가 바퀴마다 붙는 값과 견주어 보세요.
정답
모두 세 줄입니다.
1 e
2 a
3 undefined| 줄 | 바뀐 이름 | 값 | 출력 |
|---|---|---|---|
| 2 | n | 3 | |
| 3 | i | 1 | |
| 3 | 조건 i <= n | true | |
| 4 | 1 e | ||
| 3 | i | 2 | |
| 3 | 조건 i <= n | true | |
| 4 | 2 a | ||
| 3 | i | 3 | |
| 3 | 조건 i <= n | true | |
| 4 | 3 undefined | ||
| 3 | i | 4 | |
| 3 | 조건 i <= n | false |
자리 번호는 0부터라 's'는 0번입니다. i가 1부터 시작해 's'를 건너뛰고, <= 때문에 없는 3번 자리까지 꺼내 오류 없이 undefined를 찍습니다.
흔한 오답은 1 s · 2 e · 3 a입니다. 첫 글자를 1번으로 센 것입니다. 마지막 줄 대신 오류를 쓰면 없는 자리를 꺼내면 바로 오류가 난다고 본 것입니다(없으면 오류라는 생각). 세 글자를 차례로 찍으려면 let i = 0과 i < n으로 씁니다. 0부터 셀 때 n번 도는 조건은 i < n입니다.
문제 4
1부터 3까지 더한 합과, 마지막으로 더한 수를 찍으려 합니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요. 오류로 멈추면 찍힌 줄 다음에 오류 메시지의 …Error: 줄만 써도 됩니다.
let sum = 0;
for (let i = 1; i < 4; i++) {
sum = sum + i;
}
console.log(sum);
console.log(i);
힌트
6번 줄의 i가 붙은 값을 찾아 위로 거슬러 올라가 보세요.
힌트 둘
2번 줄에서 i를 만든 곳이 어느 중괄호의 머리인지 보세요.
정답
6 한 줄을 찍고 6번 줄에서 멈춥니다.
6main.js:6console.log(i); ^ ReferenceError: i is not defined at main.js:6:13- 2~4번 줄: 세 바퀴를 돌며 sum이 1, 3, 6에 차례로 다시 붙습니다.
- 5번 줄: 반복 앞에서 만든 sum은 반복 뒤에도 있어 6을 찍습니다.
- 6번 줄:
for머리에서let으로 만든 i는 그 반복의 중괄호 안에서만 삽니다. 반복을 나오며 사라져ReferenceError로 멈춥니다.
흔한 오답은 6 다음 3까지 쓴 답입니다. 반복이 끝나도 i가 마지막 값에 붙은 채 남는다고 본 것입니다. 마지막으로 더한 수를 쓰려면 반복 앞에서 let last = 0;을 만들고 덩어리 안에서 다시 붙여 둡니다(규칙 4).
파이썬에서는 반복이 끝나도 i가 마지막 값에 붙은 채 남습니다 — 자바스크립트는 for (let i …)의 i가 반복 밖에 없습니다.
다시 볼 레슨: for의 세 칸
문제 5
세 번 되풀이한 뒤 멈추려 합니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요. 오류로 멈추면 찍힌 줄 다음에 오류 메시지의 …Error: 줄만 써도 됩니다.
let n = 0;
console.log('시작');
while (True) {
n = n + 1;
if (n === 3) {
break;
}
}
console.log(n);
힌트
3번 줄의 조건 자리에 쓴 낱말이 무엇인지 보세요.
정답
시작 한 줄을 찍고 3번 줄에서 멈춥니다.
시작main.js:3while (True) { ^ ReferenceError: True is not defined at main.js:3:8참 값은 소문자 true입니다. 대문자로 시작한 True는 만든 적 없는 이름이라, 3번 줄이 조건을 계산하다 ReferenceError로 멈춥니다. 실행 중 오류라 앞에서 찍은 시작은 남습니다. 3번 줄을 while (true) {로 고치면 시작과 3이 찍힙니다.
흔한 오답은 시작 다음 3까지 쓴 답입니다. True를 참 값으로 본 것입니다.
파이썬에서는 while True:처럼 대문자 True — 자바스크립트는 소문자 true이고, True는 없는 이름입니다.
다시 볼 레슨: 같음과 비교 · break와 continue
문제 6
사흘 동안 날마다 500원씩 늘려 저금합니다(500원 · 1000원 · 1500원). 모은 돈을 찍으려고 아래처럼 썼습니다. 무엇이 찍힐까요? 한 줄을 글자 그대로 쓰세요.
let total = 0;
for (let i = 1; i < 4; i++) {
total = i * 500;
}
console.log(total);
힌트
3번 줄이 total을 무엇에 붙이는지, 바퀴마다 적어 보세요.
정답
1500| 줄 | 바뀐 이름 | 값 | 출력 |
|---|---|---|---|
| 1 | total | 0 | |
| 2 | i | 1 | |
| 2 | 조건 i < 4 | true | |
| 3 | total | 500 | |
| 2 | i | 2 | |
| 2 | 조건 i < 4 | true | |
| 3 | total | 1000 | |
| 2 | i | 3 | |
| 2 | 조건 i < 4 | true | |
| 3 | total | 1500 | |
| 2 | i | 4 | |
| 2 | 조건 i < 4 | false | |
| 5 | 1500 |
3번 줄은 바퀴마다 total을 그날 저금한 돈에 다시 붙일 뿐이라, 마지막 날의 1500만 남습니다.
흔한 오답은 3000입니다. 이름이 total이니 자바스크립트가 알아서 더해 준다고 본 것입니다(이름이 뜻을 정한다는 생각). 모으려면 total = total + i * 500;처럼 더하는 식을 씁니다(규칙 6).
다시 볼 레슨: 합 모으기와 세기
문제 7
카페 앱에서 받은 포인트 '500'(글)을 세 번 모읍니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.
let total = 0;
for (let i = 0; i < 3; i++) {
total = total + '500';
}
console.log(total);
console.log(typeof total);
힌트
3번 줄의 + 양쪽 값의 종류를 첫 바퀴부터 보세요.
정답
0500500500
string- 첫 바퀴:
0 + '500'은 한쪽이 글자라 0을 글자로 바꿔 이어 '0500'이고, total이 그 글자에 붙습니다. - 둘째 · 셋째 바퀴: 글자 뒤에 '500'을 또 이어 '0500500', '0500500500'이 됩니다.
- 6번 줄: total은 글자라
string입니다.
흔한 오답은 1500과 number입니다. 따옴표 안의 500도 수처럼 더한다고 본 것입니다(문자열과 수를 가리지 않는 생각). 받은 글은 Number('500')으로 수를 만든 뒤 더합니다.
다시 볼 레슨: 수·글자·불리언과 typeof · 합 모으기와 세기
문제 8
다음 코드가 하는 일로 알맞은 것을 고르세요.
let total = 0;
for (let n = 1; n <= 12; n++) {
if (n % 4 === 0) {
continue;
}
total = total + n;
}
console.log(total);
- ① 1부터 12까지 가운데 4의 배수만 더해 찍는다
- ② 1부터 12까지 가운데 4의 배수를 빼고 나머지를 더해 찍는다
- ③ 4의 배수를 처음 만나면 거기서 멈추고, 그때까지의 합을 찍는다
힌트
4번 줄의 continue를 만나면 그 바퀴의 어느 줄을 건너뛰는지, 반복은 계속되는지 보세요.
정답
② — 4의 배수일 때 continue가 6번 줄(더하기)을 건너뛰고 다음 수로 갑니다. 반복은 12까지 계속되고, 나머지 수만 total에 더해집니다.
54- ①
continue가 든 갈래를 '맞으면 더하기'로 거꾸로 읽었습니다. 6번 줄은 if 덩어리 밖이라 4의 배수가 아닐 때 실행됩니다. 4의 배수만 더하면 24입니다. - ③
continue를 반복을 끝내는break로 봤습니다.continue는 이번 바퀴만 건너뜁니다.break였다면 4를 만나 멈춰 6(1 + 2 + 3)이 찍힙니다.
다시 볼 레슨: break와 continue · 합 모으기와 세기
문제 9
3개마다 쿠폰을 주는 도장 계산기를 나흘 동안 돌렸습니다. 3일째에 쿠폰이 나와 쿠폰 3과 도장 1이 찍혀야 하는데 도장 0만 찍혀서, 3번 줄 다음에 찍는 줄을 넣어 돌렸더니 이렇게 찍혔습니다.
let stamps = 0;
for (let i = 1; i < 5; i++) {
stamps = stamps + 1;
console.log('stamps', stamps);
if (stamps === 3) {
console.log('쿠폰', i);
}
stamps = 0;
}
console.log('도장', stamps);
stamps 1
stamps 1
stamps 1
stamps 1
도장 0찍힌 값이 예측과 처음 갈리는 곳을 보고, 고칠 곳을 고르세요.
- ① 5번 줄 —
stamps === 3을stamps >= 3으로 고친다 - ② 10번 줄 — 반복 뒤에 찍는 줄을 고친다
- ③ 8번 줄 —
stamps = 0;을 if 덩어리 안(6번 줄 다음)으로 옮긴다
힌트
둘째 날에 stamps가 몇이어야 하는지 예측을 먼저 적고, 찍힌 값과 견주어 보세요.
정답
③ — 예측은 날마다 1, 2, 3, 1인데, 둘째 날에 벌써 1이 찍혀 처음 갈립니다. 첫날 끝의 8번 줄이 if 덩어리 밖이라 날마다 stamps를 0으로 되돌렸기 때문입니다. 8번 줄을 6번 줄 다음(if 덩어리 안)으로 옮기고 찍어 본 4번 줄을 지우면 이렇게 찍힙니다.
let stamps = 0;
for (let i = 1; i < 5; i++) {
stamps = stamps + 1;
if (stamps === 3) {
console.log('쿠폰', i);
stamps = 0;
}
}
console.log('도장', stamps);쿠폰 3
도장 1- ① 조건 때문에 쿠폰이 안 나온다고 봤습니다. stamps가 늘 1이라
>=연산자로 바꿔도 걸리지 않고도장 0이 그대로 찍힙니다. - ② 틀린 값이 찍힌 줄을 고치면 된다고 봤습니다. 10번 줄은 stamps가 붙은 값을 찍을 뿐이고, 틀린 값은 8번 줄에서 처음 생겼습니다.
다시 볼 레슨: 값을 찍어 보며 고치기 · 도장 계산기 만들기
문제 10
1부터 4까지 더해 10을 찍으려 했는데 14가 찍힙니다. 몇 번 줄을 어떻게 고쳐야 할까요?
let total = 0;
let n = 1;
while (n <= 4) {
n = n + 1;
total = total + n;
}
console.log(total);
14힌트
첫 바퀴를 줄마다 따라가며 total의 예측과 실제를 나란히 적어 보세요. 첫 바퀴에 더해야 할 수는 1입니다.
정답
4번 줄 n = n + 1;을 5번 줄 아래로 옮깁니다.
let total = 0;
let n = 1;
while (n <= 4) {
total = total + n;
n = n + 1;
}
console.log(total);10첫 바퀴를 예측과 실제로 나란히 따라가면 처음 갈리는 줄이 보입니다.
| 줄 | 바뀐 이름 | 예측 | 실제 |
|---|---|---|---|
| 3 | 조건 n <= 4 | true | true |
| 4 | n | 1 | 2 |
| 5 | total | 1 | 2 |
1을 더해야 할 첫 바퀴에 4번 줄이 n을 먼저 2에 다시 붙여, 5번 줄이 2를 더했습니다. 바퀴마다 하나 큰 수를 더해 2 + 3 + 4 + 5 = 14가 됐습니다. 수를 바꾸는 줄을 더한 뒤로 옮기면 1 + 2 + 3 + 4 = 10입니다.
- 다르게 고쳐도 되는 곳: 2번 줄을
let n = 0;으로, 3번 줄을n < 4로 함께 고쳐도 10이 찍힙니다. 다만 두 곳을 고쳐야 합니다. - 흔한 오답은 3번 줄 조건만
n < 4로 고치는 것입니다. 처음 갈리는 줄이 아닌 곳을 고쳐 9가 찍힙니다(2 + 3 + 4).
let total = 0;
let n = 1;
while (n < 4) {
n = n + 1;
total = total + n;
}
console.log(total);9다시 볼 레슨: while과 추적 표 · 값을 찍어 보며 고치기
문제 11 (만들어 보기)
계단 오르기 운동 기록기를 만들어 봅니다. 1일째 10칸, 2일째 20칸처럼 날마다 10칸씩 더 오릅니다. n일 동안 오른 칸 수를 모두 더해 찍습니다. n이 5면 이렇게 나와야 합니다.
150칸
아래 뼈대의 주석 셋 아래를 채우세요. 다 쓰면 1번 줄의 n을 8로 바꿔 따라가 봅니다. 360칸이 나와야 합니다.
const n = 5;
// 1. 합을 0으로
// 2. 하나씩 꺼내 더하기
// 3. 끝나고 쓰기
힌트
주석 셋마다 그 아래에서 할 일을 말로 한 줄씩 먼저 적어 보세요.
힌트 둘
i일째 오르는 칸 수는 i * 10입니다. i를 1부터 n까지 하나씩 바꾸는 반복 안에서 그 수를 합에 더합니다.
정답
모범 답입니다.
const n = 5;
// 1. 합을 0으로
let total = 0;
// 2. 하나씩 꺼내 더하기
let i = 1;
while (i <= n) {
total = total + i * 10;
i++;
}
// 3. 끝나고 쓰기
console.log(`${total}칸`);150칸n이 8이면 total은 10 + 20 + … + 80 = 360입니다.
- 다르게 써도 되는 곳: 같은 일을 for로
for (let i = 1; i <= n; i++)머리 한 줄에 써도 됩니다(모범 답은 폰 화면 폭 때문에 while로 나눴습니다). 그날 칸 수에 이름을 붙여(const step = i * 10;) 더해도 됩니다. - 찍은 화면이 위와 같고 둘째 시험 값(8)도 맞으면 맞습니다.
- 흔한 오답 셋:
total = i * 10;처럼 더하지 않으면 마지막 날의50칸만 남습니다(이름이 뜻을 정한다는 생각). 조건을i < n으로 쓰면 5일째를 빼100칸입니다.<연산자에 끝 수도 든다고 본 것입니다(끝도 든다는 생각). 찍는 줄을 반복 안에 두면10칸부터150칸까지 다섯 줄이 찍힙니다(규칙 4).
문제 12 (만들어 보기)
이번에는 빈 데서 씁니다. 카페 회원 아이디에는 빈칸을 쓸 수 없습니다. 아이디에서 처음 나오는 빈칸의 자리 번호를 찾아 빈칸 4처럼 찍고, 빈칸이 없으면 빈칸 없음을 찍는 프로그램을 쓰세요. 아이디는 const id = 'flow cafe';로 두고 시작합니다. 이렇게 나와야 합니다.
빈칸 4
다 쓰면 아이디를 'flowcafe'로 바꿔 따라가 봅니다. 빈칸 없음이 나와야 합니다. 'a b c'로 바꾸면 처음 빈칸 하나만 빈칸 1로 찍혀야 합니다.
힌트
찾으면 멈추기 틀의 하위 목표 셋(1. 깃발 내리기 · 2. 하나씩 보며 찾으면 올리고 멈추기 · 3. 깃발 보고 쓰기)을 주석으로 먼저 쓰고, 그 아래를 채웁니다. 글자는 자리 번호 0부터 하나씩 봅니다.
정답
모범 답입니다. 주석은 줄 폭 때문에 뺐습니다 — 3번 줄이 '1. 깃발 내리기', 4~10번 줄이 '2. 하나씩 보며 찾으면 올리고 멈추기', 11~13번 줄이 '3. 깃발 보고 쓰기'입니다.
const id = 'flow cafe';
const n = id.length;
let found = false;
for (let i = 0; i < n; i++) {
if (id[i] === ' ') {
console.log('빈칸', i);
found = true;
break;
}
}
if (!found) {
console.log('빈칸 없음');
}빈칸 4'flowcafe'면 빈칸을 한 번도 만나지 않아 깃발이 내린 그대로이고, 12번 줄이 빈칸 없음을 찍습니다. 'a b c'면 1번 자리에서 찍고 break로 멈춰, 3번 자리의 빈칸은 보지 않습니다.
- 다르게 써도 되는 곳: 찾은 자리에 이름을 붙여(
pos = i;) 반복 뒤에서if (found) { … } else { … }로 찍어도 됩니다.if (!found)대신if (found === false)도 같습니다. - 찍은 화면이 위와 같고 둘째 · 셋째 시험 값도 맞으면 맞습니다.
- 흔한 오답 하나는
break를 빠뜨리는 것입니다. 'flow cafe'에서는 같아 보이지만 'a b c'에서빈칸 1과빈칸 3두 줄이 찍힙니다. 첫 시험 값 하나로는 드러나지 않아 값 셋으로 봅니다. - 다른 흔한 오답은
빈칸 없음을 반복 안의 else 갈래에서 찍는 것입니다. 빈칸이 아닌 글자마다 찍혀빈칸 없음이 네 번 찍힌 뒤빈칸 4가 나옵니다. 깃발은 반복이 끝난 뒤에 봅니다.
다시 볼 레슨: break와 continue · for의 세 칸 · 인덱스와 자르기