두 개의 input에 복소수(complex number)가 string 으로 주어집니다. 복소수란 a+bi 의 형태로, 실수와 허수로 이루어진 수입니다.
input으로 받은 두 수를 곱해서 반환해주세요. 반환하는 표현도 복소수 형태의 string 이어야 합니다.
복소수 정의에 의하면 (i^2)는 -1 이므로 (i^2) 일때는 -1로 계산해주세요.
(제곱 표현이 안 되어 i의 2제곱을 (i^2)라고 표현했습니다.)예제 1: Input: "1+1i", "1+1i" Output: "0+2i" 설명: (1 + i) * (1 + i) = 1 + i + i + i^2 = 2i 2i를 복소수 형태로 바꾸면 0+2i.
예제 2: Input: "1+-1i", "1+-1i" Output: "0+-2i" 설명: (1 - i) * (1 - i) = 1 - i - i + i^2 = -2i, -2i를 복소수 형태로 바꾸면 0+-2i.
예제 3: Input: "1+3i", "1+-2i" Output: "7+1i" 설명: (1 + 3i) * (1 - 2i) = 1 - 2i + 3i -6(i^2) = 1 + i + 6, 7+i를 복소수 형태로 바꾸면 7+1i.
가정
input은 항상 a+bi 형태입니다. output도 a+bi 형태로 나와야 합니다.const complexNumberMultiply = (a, b) => { // 여기에 코드를 작성해주세요. }
TIL
string만 보면 split()함수로 배열로 만드는 습관이 생겼다.
개인적으로 이런 방법이 이해하기 편하나 다른 함수는 없는지 찾아볼 필요가 있겠다..
풀이
1. 입력받은 string타입의 복소수를 [정수, 허수]로 변환한다
2. 결과값은 (정수*정수 - 허수*허수) + (정수*허수 + 허수*정수)i 로 반환한다
const complexNumberMultiply = (a, b) => {
// 여기에 코드를 작성해주세요.
a = a.split("i").join("").split("+");
b = b.split("i").join("").split("+");
return (a[0]*b[0]-a[1]*b[1]) +"+"+ (a[0]*b[1]+a[1]*b[0]) + "i";
}
풀이2 - 임창현 님
a = a.slice(0,-1).split('+');
문자로 구성된 배열을 input으로 전달하면, 문자를 뒤집어서 return 해주세요.
새로운 배열을 선언하면 안 됩니다.
인자로 받은 배열을 수정해서 만들어주세요.Input: ["h","e","l","l","o"] Output: ["o","l","l","e","h"]
Input: ["H","a","n","n","a","h"] Output: ["h","a","n","n","a","H"]
const reverseString = s => { };
처음 생각했던 방법은 split()함수를 활용하는 것이었는데
const reverseString = s => {
for(let i=1; i<s.length; i++){
s =(s[i]+s.join("").split(s[i]).join("")).split("");
}
return s;
}
...이 방법은 틀렸다. 왜냐?
배열s의 요소가 중복될수도 있기 때문이다.
.split(s[i])
👉 이 부분이 의도했던 배열s의 i번째 인덱스만 쪼개는 것이 아니라 값이 동일한 다른 요소도 쪼개면 원하는 답을 얻을 수 없다
풀이1
일단 나열해보고 반복되는 부분을 반복문으로 리팩토링 해보자
순서 \ index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | h | e | l | l | o | h | s[8] = s[0] | |||
1 | e | l | l | o | h | s.shift() | ||||
2 | e | l | l | o | e | h | s[6] = s[0] | |||
3 | l | l | o | e | h | s.shift() | ||||
4 | l | l | o | l | e | h | s[4] = s[0] | |||
5 | l | o | l | e | h | s.shift() | ||||
6 | l | o | l | l | e | h | s[2] = s[0] | |||
7 | o | l | l | e | h | s.shift() |
이렇게 하니 기준값과 반복되는 부분이 보인다!
const reverseString = s => {
for(let i=(s.length-1)*2; i>0; i-=2){
s[i] = s[0];
s.shift();
}
return s;
}
풀이2
규칙을 찾아 리팩토링 하기
순서 \ index | 0 | 1 | 2 | 3 | 4 | 5 | 실행 | 결과 |
---|---|---|---|---|---|---|---|---|
0 | h | e | l | l | o | s.unshift(s[1]) | ehello | |
1 | e | h | e | l | l | o | s.splice(s[2,1]) | ehllo |
2 | e | h | l | l | o | s.unshift(s[2]) | lehllo | |
3 | l | e | h | l | l | o | s.splice(s[3,1]) | lehlo |
4 | l | e | h | l | o | s.unshift(s[3]) | llehlo | |
5 | l | l | e | h | l | o | s.splice(s[4,1]) | lleho |
6 | l | l | e | h | o | s.unshift(s[4]) | olleho | |
7 | o | l | l | e | h | o | s.splice(s[5,1]) | olleh |
i가 1부터 5까지 반복할 때 5는 s.length보다 작으므로
다음과 같이 쓸 수 있다.
const reverseString = s => {
for(let i=1; i<s.length; i++){
s.unshift(s[i]);
s.splice(i+1,1);
}
return s;
}
TIL
- unshift(
값
) : 배열의 첫번째 요소에값
을 추가한다s = [10,20,30] console.log(s.unshift(-10)) // 4 console.log(s) // [-10,10,20,30]
- shift() : 배열의 첫번째 요소을 삭제한다
s = [10,20,30] console.log(s.shift()) // 10 console.log(s) // [20,30]
- splice(
위치
) : 배열의위치
부터 모든 요소를 삭제한다.s = [10,20,30] console.log(s.splice(1)) // [20,30] console.log(s) // [10]
위치
가 음수일 경우,length-위치
를 의미한다s = [10,20,30] console.log(s.splice(-1)) // [30] console.log(s) // [10,20]
- splice(
위치
,삭제 개수
) : 배열의위치
부터삭제개수
만큼 삭제한다- splice(
위치
, 0,값
) : 배열의위치
에값
을 추가한다- splice(
위치
,삭제 개수
,값
) : 배열의위치
부터삭제개수
만큼 삭제하고값
을 추가한다.값
은값,값,값,...
처럼 여러개를 넣을 수 있다
다른 풀이3
훨씬 쉬운 방법이 있었다 : 메소드 reverse()를 쓰면 됨!
const reverseString = s => {
return s.reverse();
}
문제
양수로 이루어진 m x n 그리드를 인자로 드립니다. 상단 왼쪽에서 시작하여, 하단 오른쪽까지 가는 길의 요소를 다 더했을 때, 가장 작은 합을 찾아서 return 해주세요.
한 지점에서 우측이나 아래로만 이동할 수 있습니다.Input: [ [1,3,1], [1,5,1], [4,2,1] ] Output: 7
설명: 1→3→1→1→1 의 합이 제일 작음
const minPathSum = grid => { };
문제
주어진 숫자 배열에서, 0을 배열의 마지막쪽으로 이동시켜주세요.
원래 있던 숫자의 순서는 바꾸지 말아주세요.
(새로운 배열을 생성해서는 안 됩니다.)Input: [0,1,0,3,12] Output: [1,3,12,0,0]
풀이
1. nums에 있는 0의 개수를 구한다 => count
2. nums에 0이 없을 때까지 0을 제거한다
3. 1.에서 구한 count수만큼 nums 뒤에 추가한다
소스코드
const moveZeroes = nums => {
let count = nums.join("").split(0).length-1
while(nums.indexOf(0)!==-1){
nums.splice(nums.indexOf(0), 1)
}
for(let i=0; i<count; i++){
nums.push(0);
}
return nums;
}
TIL
1. 0의 개수만큼 반복해서 추가하는 방법으로 repeat()함수를 떠올렸지만 str.repeat(0)은 str에 0을 추가하는 것이었기에 쓸 수가 없었다
재귀 알고리즘
오늘은 재귀알고리즘에 대한 문제입니다. 재귀(recursion)란, 자신을 정의할 때 자기 자신을 호출하는 방법을 뜻합니다. 프로그래밍의 함수정의에서 많이 사용됩니다.
예)const countdown = n => { console.log(n); countdown(n-1); } countdown(10);
countdown 함수는 받은 인자를 console로 출력합니다. 그런데 위의 함수를 실행하면 10에서 시작해서 무한으로 마이너스 값까지 내려갑니다.
그래서 재귀함수는 아래의 절차가 꼭 필요합니다. 언제 멈출것인가?
위를 고려해 0이 되면 더이상 재귀를 이어나가지 않도록 종료 조건을 추가하겠습니다.
const countdown = n => { console.log(n); if (n === 0) return; countdown(n-1); } countdown(10);
재귀의 이론은 위와 같이 아주 간단합니다. 재귀를 더 공부하고 싶은 분은 인터넷에 재귀 문제를 찾아 더 풀어보셔도 좋고, 알고리즘 책에서 재귀 부분만 더 읽으셔도 좋습니다.
문제
재귀를 사용하여 팩토리얼(factorial)을 구하는 함수를 구현해주세요. 팩토리얼이란 1에서부터 n까지의 정수를 모두 곱한것을 말합니다.1! = 1 2! = 1 * 2 5! = 1 * 2 * 3 * 4 * 5
풀이:
1. n=1이면 factorial(1) = 1
2. n=2이면 2*factorial(1) = 2*1 = 2
3. n=3이면 3*factorial(2) = 3*2 = 6
3. n=3이면 4*factorial(3) = 4*6 = 24
function factorial(n){
if(n === 1){
return 1;
}
return n * factorial(n - 1)
}
👉 test2에서 RangeError: Maximum call stack size exceeded
가 떴는데 이유를 모르겠다