If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Finish the solution so that it returns the sum of all the multiples of 3 or 5 below the number passed in.
Note: If the number is a multiple of both 3 and 5, only count it once.
🚩 문제해설
만약에 자연수 10이 주어졌을 때, 10보다 작은 3의 배수 혹은 5의 배수는 3,5,6,9이다. 이것의 총 합은 23이다. 이처럼 주어진 수(여기선 10)보다 작은 3이나 5의 배수의 총합을 구하시오. 단 공배수의 경우는 한번만 카운팅한다.
ps. multiple : 배수
요약 : 주어진 수(자연수)보다 작은 3이나 5의 배수의 총합을 구하시오.
```javascript
1 function solution(number){
2 let sum = 0;
3 for(let i = 1; i < number; i++){
4 if(!(i % 3) || !(i % 5)) sum += i;
5 }
6 return sum;
7 }
```
> 4번째 라인에서 `i % 3 === 0 || i % 5 === 0` 를 다르게 써본 부분이다. 자바스크립트에서는 **0이 false**를 나타내기 때문에 나눠 떨어진 값이 0인 경우는 false이고 그의 반대 ( ! )는 true로 하여 조건을 걸어준 것이다. 저런식으로 많이 사용하는 것 같아서 사용해봤다.
```javascript
1 function solution(number){
2 return Array.from({length:number},(v,i) => i)
3 .reduce((a,v) => {
4 if(!(v % 3) || !(v % 5)) return a + v;
5 else return a;
6 }, 0);
7 }
```
> 첫번째로 Array.from()은 배열을 생성할 때 사용하는 메소드이다. parameter로는 **length 속성을 지닌 객체(유사객체)**가 필요하다. 그 외 배열의 요소에 맵핑될 수 있는 함수가 들어갈 수 있다. 주어진 자연수보다 작은 수 중에 배수인 수를 모두 확인해봐야 하기 때문에 1부터 주어진 수보다 1 작은 수까지의 자연수가 차례대로 배열의 요소가 되면 된다.
두번째 배열의 수 중에서 배열 안에서 3과 5의 배수를 찾아서 해당 값들을 모두 더한, 누적값을 구하는 것이기때문에 reduce()를 사용하였다. 여기서 주의해야할 점이 있다. 초기값을 어떻게 설정하는지에 따라서 error가 발생할 수 있다. 만약에 빈 배열이 들어오게 되면 초기값이 없는 경우는 error가 발생한다. 그렇기 때문에 reduce(callback, initial value)
에서 initial value를 0으로 주어여한다.solution = n => n <= 0 ? 0 : Array.from({length: n}, (_,i) => (i%3==0||i%5==0) ? i : 0)
.reduce((x,y) => x + y);
Array.from()에서 요소를 맵핑할 때부터 3의 배수 혹은 5의 배수인 수만 배열에 담도록 하였다. 또한 삼항연산자를 통해서 빈 배열을 골라내었다. 그 후 reduce()를 통해서 배열의 모든 수를 더해서 결과값을 도출하였다.
function solution(number){
var n3 = Math.floor(--number/3), n5 = Math.floor(number/5), n15 = Math.floor(number/15);
return (3 * n3 * (n3 + 1) + 5 * n5 * (n5 + 1) - 15 * n15 * (n15+1)) /2;
}
두가지의 수학적 개념을 이용한 풀이이다. 2가지 개념이 필요하다. 첫번째는 합집합의 연산, 두번째는 등차수열의 합을 구하는 공식이다. 여기서 n3, n5, n15의 의미는 주어진 숫자안에 들어있는 3의 배수, 5의 배수 15의 배수의 개수이다. 아래 이미지를 참고하면 위 코드를 수학적 의미로 이해 할 수 있다.
수학적으로 풀이를 보고 다들 놀라는 댓글들이 많았다. 하지만 한편으로는 직관적이지 못하고 이해하기 힘들다는 의견들이 많이 있었다. 나 역시 저 풀이를 처음 봤을 때 공통 배수인 15를 뺀다는 것은 알았지만, 각각의 식의 정확한 의미는 연산을 해보고 나서야 알게 되었다. 저 풀이를 좀 더 직관적이게 바꿔 놓은 풀이들도 있었지만 그렇게 되면 코드가 그만큼 길어지게 된다. 언제나 각각의 풀이에 대해 장단점은 존재하는 것 같다. 중요한 것은 수학적 개념을 코드로 구현했다는 것. 다양한 문제 풀이 방안에 있어서 수학적 개념의 필요성에 대해서 알 수 있는 문제였다.
🚀 문제를 풀어나갈 때 생각의 흐름을 정리합니다. 또한 새로운 풀이에 대한 코드를 분석하고 모르는 부분에 대해서 정리합니다. 생각이 다른 부분에 대한 피드백은 언제나 환영합니다. 틀린 내용에 대한 피드백 또한 항상 감사합니다.