돌아가기

주어진 숫자까지의 모든 숫자 더하기

중요도: 5

숫자 1 + 2 + ... + n을 계산하는 함수 sumTo (n)을 만들어보세요.

예시:

sumTo(1) = 1
sumTo(2) = 2 + 1 = 3
sumTo(3) = 3 + 2 + 1 = 6
sumTo(4) = 4 + 3 + 2 + 1 = 10
...
sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050

아래 방법을 사용해 세 가지 답안을 만들어보세요.

  1. for 반복문 사용하기
  2. 재귀 사용하기(n > 1일 때 sumTo(n) = n + sumTo(n-1))
  3. 등차수열 공식 사용하기

예시:

function sumTo(n) { /*... 답안은 여기에 작성 ... */ }

alert( sumTo(100) ); // 5050

더 생각해보기 1: 세 가지 방법 중 어떤 방법이 가장 빠른가요? 어떤 방법이 가장 느린가요? 이유도 함께 제시해주세요.

더 생각해보기 2: 재귀를 사용해 sumTo (100000)를 계산할 수 있을까요?

반복문 사용하기:

function sumTo(n) {
  let sum = 0;
  for (let i = 1; i <= n; i++) {
    sum += i;
  }
  return sum;
}

alert( sumTo(100) );

재귀 사용하기:

function sumTo(n) {
  if (n == 1) return 1;
  return n + sumTo(n - 1);
}

alert( sumTo(100) );

등차수열의 합공식 sumTo(n) = n*(n+1)/2 사용하기:

function sumTo(n) {
  return n * (n + 1) / 2;
}

alert( sumTo(100) );

더 생각해보기 1: 등차수열의 합공식을 사용하는 방법이 가장 빠릅니다. n에 관계없이 오직 세 개의 연산만 수행하면 되니까요. 수학은 항상 뭔가에 도움을 줍니다!

반복을 사용하는 방법은 두 번째로 빠릅니다. 재귀를 사용하는 방법과 반복문을 사용하는 방법 모두 같은 수의 숫자를 더하는 것에서 같지만, 재귀를 사용하는 방법은 중첩 호출과 실행 스택 관리가 추가로 필요하기 때문에 더 많은 자원을 소비합니다. 따라서 속도가 더 느리죠.

더 생각해보기 2: 몇몇 자바스크립트 엔진은 ‘tail call’ 최적화를 지원합니다. 위 함수 sumTo처럼 함수가 가장 마지막으로 수행하는 연산이 재귀 호출이라면 외부 함수는 실행을 다시 시작할 필요가 없기 때문에 엔진은 실행 컨텍스트를 기억할 필요가 없어집니다. 메모리 부담이 사라지는 거죠. 그렇기 때문에 sumTo(100000)같은 계산이 가능한 것입니다. 그런데 자바스크립트 엔진이 tail call 최적화를 지원하지 않는다면(대부분의 엔진이 이를 지원하지 않습니다) 엔진에 설정된 스택 사이즈 제한을 넘었기 때문에 최대 스택 사이즈 초과 에러가 발생합니다.