diff --git a/problem-1/problem-1.test.js b/problem-1/problem-1.test.js index c775a02..b1c5ab6 100644 --- a/problem-1/problem-1.test.js +++ b/problem-1/problem-1.test.js @@ -1,6 +1,38 @@ -const solution = (numbers) => { +// 1. 가장 익숙한 방법으로 문제를 해결해 주세요. +const solution1 = (numbers = []) => { + if(numbers.length === 0) return 0; + + return numbers.reduce((acc, cur) => acc + cur, 0); +}; + +// 2. 이번에는 재귀 함수로 문제를 해결해 주세요. +// Maximum call stack size exceeded 오류나는데 왜 나는지 모르겠습니다 +const solution2 = (numbers = []) => { + if(numbers.length === 0) return 0; + + return numbers[0] + solution2(numbers.slice(1)); }; +// 3. 꼬리 재귀 함수로 바꿔보세요. +// Maximum call stack size exceeded 오류나는데 왜 나는지 모르겠습니다 +const solution3 = (numbers = [], acc = 0) => { + if(numbers.length === 0) return acc; + + return solution3(numbers.slice(1), acc + numbers[0]); +} + +// 4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. +const solution = (numbers = []) => { + if(numbers.length === 0) return 0; + + let acc = 0; + for(let number of numbers){ + acc += number; + } + + return acc; +} + test('빈 배열은 0을 반환한다', () => { expect(solution([])).toBe(0); }); diff --git a/problem-2/problem-2.test.js b/problem-2/problem-2.test.js index 458a6b8..a934b17 100644 --- a/problem-2/problem-2.test.js +++ b/problem-2/problem-2.test.js @@ -1,6 +1,54 @@ -const solution = (n) => { + +// 1. 가장 익숙한 방법으로 문제를 해결해 주세요. +const solution1 = (n) => { + if(n <= 0) return 0; + if(n === 1) return 1; + + let array = [0, 1]; + + for(let i=2; i <= n; i+=1){ + array[i] = array[i - 2] + array[i - 1]; + } + + return array[n]; }; +//2. 이번에는 재귀 함수로 문제를 해결해 주세요. +const solution2 = (n) => { + if(n <= 0) return 0; + if(n === 1) return 1; + + return solution2(n-2) + solution2(n-1); +} + +//3. 꼬리 재귀 함수로 바꿔보세요. +const solution3 = (n, prev = 0, curr = 1) => { + if(n <= 0) return prev; + if(n === 1) return curr; + + return solution3(n-1, curr, prev + curr); + +} + +//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. +const solution = (n) => { + let param = n, + prev = 0, + curr = 1, + sumResult = 0; + + while(true){ + if(param <= 0) return prev; + if(param === 1) return curr; + + sumResult = prev + curr; + prev = curr; + curr = sumResult; + param -= 1; + } +} + + test('음수가 주어지면 0을 반환한다', () => { expect(solution(-1)).toBe(0); }); diff --git a/problem-3/problem-3.test.js b/problem-3/problem-3.test.js index 7319eb8..d575eab 100644 --- a/problem-3/problem-3.test.js +++ b/problem-3/problem-3.test.js @@ -1,4 +1,50 @@ +//1. 가장 익숙한 방법으로 문제를 해결해 주세요. +const solution1 = (n) => { + if(n < 2) return n.toString(); + + let result = []; + + while(true){ + if(n < 2){ + result.push(n); + return result.reverse().join(''); + } + + const remainder = n % 2; + result.push(remainder); + n = Math.floor(n / 2); + } +}; + +//2. 이번에는 재귀 함수로 문제를 해결해 주세요. +const solution2 = (n) => { + if(n < 2) return n.toString(); + + const remainder = n % 2, + quotient = Math.floor(n / 2); + + return `${solution2(quotient)}${remainder.toString()}`; + +}; + +//3. 꼬리 재귀 함수로 바꿔보세요. +const solution3 = (n, result = '') => { + if(n < 2) return `${n}${result}`; + + return solution3(Math.floor(n / 2), n % 2 + result); +}; + +//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. const solution = (n) => { + let result = ''; + + while(true){ + if(n < 2) return `${n}${result}`; + + const remainder = n % 2; + n = Math.floor(n / 2); + result = `${remainder}${result}`; + } }; test('이진수 문자열을 반환한다', () => { diff --git a/problem-4/problem-4.test.js b/problem-4/problem-4.test.js index 19f5cb0..ec54a71 100644 --- a/problem-4/problem-4.test.js +++ b/problem-4/problem-4.test.js @@ -1,4 +1,56 @@ -const solution = () => { +//1. 가장 익숙한 방법으로 문제를 해결해 주세요. +const solution1 = (binaryString) => { + let result = 0; + + for(let i = 0; i < binaryString.length; i++){ + const binaryNumber = parseInt(binaryString[i], 10), + index = binaryString.length - (i + 1); + + result += binaryNumber * (2 ** index); + } + + return result; + }; + +// 2. 이번에는 재귀 함수로 문제를 해결해 주세요. +const solution2 = (binaryString, binaryIndex = 0, stringIndex = binaryString.length - 1) => { + if (binaryString === '0' || stringIndex < 0) return 0; + if (binaryString === '1') return 1; + + const binaryNumber = parseInt(binaryString[binaryIndex], 10), + result = binaryNumber * ( 2 ** stringIndex); + + return result + solution2(binaryString, binaryIndex + 1, stringIndex - 1); +}; + +// 3. 꼬리 재귀 함수로 바꿔보세요. +const solution3 = (binaryString, binaryIndex = 0, stringIndex = binaryString.length - 1, result = 0) => { + if (binaryString === '0') return 0; + if (binaryString === '1') return 1; + if (stringIndex < 0) return result; + + return solution3(binaryString, binaryIndex + 1, stringIndex - 1, result + (2 ** stringIndex) * parseInt(binaryString[binaryIndex], 10)); +}; + +// 4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. +const solution = (binaryString) => { + let result = 0, + stringIndex = binaryString.length - 1, + binaryIndex = 0; + + while (true) { + if (binaryString === '0' || stringIndex < 0) { + return 0 + result; + } + + if (binaryString === '1') { + return 1 + result; + } + result += (2 ** stringIndex) * parseInt(binaryString[binaryIndex], 10); + + stringIndex--; + binaryIndex++; + } }; test('10진수 숫자를 반환한다', () => { diff --git a/problem-5/problem-5.test.js b/problem-5/problem-5.test.js index 20a8fab..f1006c5 100644 --- a/problem-5/problem-5.test.js +++ b/problem-5/problem-5.test.js @@ -1,4 +1,35 @@ -const solution = () => { +//1. 가장 익숙한 방법으로 문제를 해결해 주세요. +const solution1 = (a, b) => { + if(b === 0) return a; + + return solution1(b, a % b); +}; + +//2. 이번에는 재귀 함수로 문제를 해결해 주세요. +const solution2 = (a, b) => { + if(b === 0) return a; + + return solution2(b, a % b); +}; + +//3. 꼬리 재귀 함수로 바꿔보세요. +const solution3 = (a, b) => { + if(b === 0) return a; + + return solution3(b, a % b); +}; + +//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. +const solution = (a, b) => { + while (true) { + if (a % b === 0) { + return b; + } + + const temp = a; + a = b; + b = temp % b; + } }; test('최대 공약수를 반환한다', () => { diff --git a/problem-6/problem-6.test.js b/problem-6/problem-6.test.js index 059e2b8..4241bc3 100644 --- a/problem-6/problem-6.test.js +++ b/problem-6/problem-6.test.js @@ -1,4 +1,44 @@ -const solution = (n) => { +//1. 재귀 함수로 문제를 해결해 주세요. +const solution1 = (n) => { + if (n < 0) { + return 0; + } + + if (n === 0 || n === 1) { + return 1; + } + return solution1(n - 3) + solution1(n - 2) + solution1(n - 1); +}; +//2. 다이나믹 프로그래밍으로 최적화 해주세요. +const solution2 = (n, memo = []) => { + if (n < 0) { + return 0; + } + + if (n === 0 || n === 1) { + return 1; + } + + if(!memo[n]){ + memo[n] = solution2(n - 3, memo) + solution2(n - 2, memo) + solution2(n - 1, memo); + } + + return memo[n]; +}; + +const solution = (n, current = 2, a = 0, b = 1, c = 1) => { + if (n < 0) { + return 0; + } + + if (n === 0 || n === 1) { + return 1; + } + + if(n === current) return a + b + c; + + return solution(n, current + 1, b, c, a + b + c); + }; test('계단에 오를 수 있는 가지 수를 반환한다', () => {