Sum of the first nth term of Series<7 kyu>

jjanmo·2019년 12월 26일
0

Codewars에서 뒹굴기

목록 보기
3/32

🚀 문제를 풀어나갈 때 생각의 흐름을 정리합니다. 또한 새로운 풀이에 대한 코드를 분석하고 모르는 부분에 대해서 정리합니다. 생각이 다른 부분에 대한 피드백은 언제나 환영합니다. 틀린 내용에 대한 피드백 또한 항상 감사합니다.

문제링크

문제

Task:
Your task is to write a function which returns the sum of following series upto nth term(parameter).
Series: 1 + 1/4 + 1/7 + 1/10 + 1/13 + 1/16 +...
Rules:

  • You need to round the answer to 2 decimal places and return it as String.
  • If the given value is 0 then it should return 0.00
  • You will only be given Natural Numbers as arguments.
Examples:
SeriesSum(1) => 1 = "1.00"
SeriesSum(2) => 1 + 1/4 = "1.25"
SeriesSum(5) => 1 + 1/4 + 1/7 + 1/10 + 1/13 = "1.57"
NOTE: In PHP the function is called series_sum().

👉 문제해석
난이도가 낮은 문제들은 기본적으로 문제에서 식을 주어지는 경우가 많은 것 같다. 어제 풀었던 문제와 마찬가지로 이 문제도 식을 주고 그 식을 일반화하여 코드로 구현하면 되는 문제이다. Series: 1 + 1/4 + 1/7 + 1/10 + 1/13 + 1/16 +... 이 식을 일반화하여서 조건에 맞게 값을 리턴하면 된다.

문제접근

  • 첫번째 생각 : 주어진 식에 대한 규칙을 찾았다. 분모가 3씩 커지는 등차수열을 생각하였다.

    function SeriesSum(n) {
        let sum = 0.00;
        for(let  i = 0; i < n; i++){
          sum += 1/(3*i+1);
        }
        return String(sum.toFixed(2));
    }
     

Best solution

이번 문제는 best solution과 clever solution이 모두 비슷하게 접근하였기 때문에 딱히 적을게 없었다. 그런데 newest solution 부문을 보던 중, 자바스크립트에서 처음보는 구문이 보여 당혹스러워서 이렇게 적게 되었다.

function SeriesSum(n, sum = 0) {
    return n ? SeriesSum(n-1, sum + 1/(1+3*(n-1))) : sum.toFixed(2)
}
  • 이 코드는 재귀적 방법을 사용하여 접근하였다. 그런데 댓글을 보다보니 문제 테스트 케이스는 통과하는 것 같지만 커스텀으로 아주 높은 수를 넣으면 통과하지 못하는 것 같다. 직접해보니 역시나 stack overflow가 발생한다. 이렇게 봤을 때 위 풀이보단 반복문으로 문제를 해결하는 것이 더 효율적이고 정확한 풀이라고 생각한다. 추후에 재귀적으로 풀어야만 하는 문제들이 등장할 것이다. 그 때 재귀적인 문제에 대해서 더 생각해도록 해야겠다.
  • 나를 당혹스럽게 만든 코드는 바로 매개변수 자리의 sum=0 이였다. 찾아보니 이것은 ES6에서 새롭게 등장한 기본 함수 매개변수(default function parameter)라고 한다. .

기본 함수 매개변수에 대해서

	function multiply(a, b){
     	return a * b; 
    } 
	
	multuple(5 * 2); 	//10
	multiple(5);		//NaN!			

기본적으로 자바스크립트의 매개변수 값은 undefined이다. 그렇기 때문에 인자가 5만 들어온 경우엔 비어있는 나머지 인자가 자동으로 undefined가 되어서 결과값이 NaN이 되는 것이다. 이와 같은 현상을 막기위해서 과거에는 매개변수에 값이 할당되지 않을 경우를 대비하여 인위적으로 값을 할당해주는 방식을 사용하였다.

	//ES5
	function multiply(a, b){
    	if(b === undefined) //값으로 비교 //if(typeof b === 'undefined') 타입으로 비교
          b = b ? b : 1; 
		return a * b;      
    }
	multuple(5 * 2); 	//10
	multiple(5);		//5
	//ES6	
	function multiply(a, b = 1){
		return a * b;      
    }
	multuple(5 * 2); 	//10
	multiple(5);		//5

ES5에서는 인자로서 들어오지 않을 값을 생각해서 그에 대한 로직을 짜줘야 했지만, ES6에서는 단지 매개변수에 기본값을 적어줌으로서 인자가 들어오지 않는 경우를 해결할 수 있게 되었다. 마찬가지로 위의 풀이에서도 function SeriesSum(n, sum = 0) 식에서 sum의 기본값을 적어줌으로서 함수의 첫 호출에서 n만을 인자로 사용하는 상황을 해결할 수 있게 된 것이다.

결론

지금 해결하고 있는 문제들은 굉장히 쉬운 문제들이다. 단지 예전에 풀던 언어와는 다른 언어로 접근하고 있을 뿐인데 매번 새로움을 느낀다.

참고

MDN 기본 매개변수
MDN undefined
ES6 기본 매개변수

profile
눈길을 걸어갈 때 어지럽게 걷지 말기를.

0개의 댓글