문제
프로그래머스 LEVEL2 - 숫자의 표현
수학 공부를 하던 **은 자연수 n을 연속한 자연수들로 표현 하는 방법이 여러개라는 사실을 알게 되었습니다. 예를들어 15는 다음과 같이 4가지로 표현 할 수 있습니다.
1 + 2 + 3 + 4 + 5 = 15 4 + 5 + 6 = 15 7 + 8 = 15 15 = 15
자연수 n이 매개변수로 주어질 때, 연속된 자연수들로 n을 표현하는 방법의 수를 return하는 solution를 완성해주세요.
제한사항
n은 10,000 이하의 자연수 입니다.
내 풀이
풀이 제출 이후 다른 사람들의 풀이를 보니 정말 다양한 풀이가 있었다. 나는 간단하게 아래와 같이 2중 for문으로 문제를 풀어보았다.
function solution(n) {
let answer = 1;
for (let i = 1; i < n / 2; i++) {
let sum = 0;
for (let j = i; j < n; j++) {
if (sum + j >= n) {
if (sum + j === n) {
answer += 1;
}
break;
} else {
sum += j;
}
}
}
return answer;
}
const result = new solution(15);
let answer = 1;
answer는 연속된 자연수들로 n을 표현하는 방법의 수를 담는 변수이다. 어떤 n(n>=1일 경우)이든 우선 자기 자신 하나로 표현하는 방법이 공통적으로 하나씩 존재하기에 answer = 1로 초기화하고 시작한다.
예1 ) n= 15일 경우, 15 = 15 인 경우
예2 ) n = 100 인 경우, 100 = 100 인 경우
for (let i = 1; i < n / 2; i++){
let sum = 0;
첫번째 for문을 돌면서, 연속된 자연수들로 n을 표현하는 방법을 구하게 된다.
여기서 sum은 연속된 자연수들의 합을 담는 변수이다.
for문을 n/2까지만 동작시키는 이유 🤨
n=15인 경우를 기준으로 n/2 = 7.5이므로 만약 i < n/2 가 아닌 i<n이라면 i = 8일때를 생각해보자.
8 다음 연속으로 오는 자연수 9가 더해지면 8 + 9 = 17로 15보다 큰 수가 된다. i = 9라면 역시 9 + 10는 15보다 큰 수가 되므로 굳이 n/2 보다 큰 자연수까지 탐색할 필요가 없다. 때문에 i < n/2 라는 조건을 적용하는 것이다.
for (let i = 1; i < n / 2; i++) { 1️⃣
let sum = 0;
for (let j = i; j < n; j++) { 2️⃣
if (sum + j >= n) {
if (sum + j === n) {
answer += 1;
}
break;
} else {
sum += j;
}
}
}
for문의 동작을 살펴보자.
연속된 자연수들 덧셈값은 sum이란 변수에 담겨지고 그 sum에 더해질 값들 중 첫번째 값이 i로 결정된다. j는 i를 기준으로 1씩 커지며 sum에 더해진다. 이때, sum에 j를 더한 값이 n 이상인 경우, sum + j 가 n 값과 동일하다면 answer는 1 증가한다. 그리고 for문2️⃣은 종료되고 i값은 1 증가한다. i < n/2 조건이 성립될때까지 이러한 형식이 반복된다.