차차로그
[JS] 2018 KAKAO BLIND RECRUITMENT[1차] > 다트 게임 본문
드디어 푼 다트게임 코테!!
5단계로 나눠서 문제를 풀어봤다.
1단계. 문자열에서 각 단계의 점수 쪼개기
정규식을 이용해 문자열을 쪼개 배열 A로 만들었다.
1단계를 거치면 ["1S","2D*","3T"]가 된다.
2단계. 숫자는 각 기회에서 얻은 기준 점수. 이 점수만 모아놓은 또다른 배열B를 만들기
["1S","2D*","3T"] 라면 [1,2,3] 배열 만들기. 이 점수를 기준으로 계산을 해야한다.
3단계. 알파벳 계산하기
S면 배열[i]에 1제곱, D는 배열[i]에 2제곱, T는 배열[i]에 3제곱하기. 3단계를 거치면 [1,4,27]이 된다.
4단계. 스타상(*), 아차상(#) 계산하기
스타상은 해당 점수와 직전 점수에 2배가 되고 아차상은 해당 점수만 마이너스가 된다.
스타상일 때는 배열[i]와 배열[i-1]에 X2하기. 아차상은 배열[i]에 X-1하기
4단계를 거치면 [2,8,27]이 된다.
5단계. 배열의 모든 값 구해서 리턴하기
리턴 값은 이 배열의 값을 모두 더해서 리턴을 시켜줘야하니 배열.reduce로 값을 더해 리턴해주면 된다!
function solution(dartResult) {
//1단계. 문자열에서 각 단계의 점수 쪼개기 => ["1S","2D*","3T"]
var answer = dartResult.match(/[0-9]{1,2}[S|D|T][*|#]?/g);
//2단계. 맨 앞 점수만 가져오기 => [ '1', '2', '3' ]
var arr = answer.map(v => v.substr(0, v.match(/\D/).index));
//3단계. S,D,T 계산 => [ 1, 4, 27 ]
arr = answer.map((v,i) => {
if(v.match(/\D/) == 'S'){
arr[i] = arr[i] ** 1;
}
if(v.match(/\D/) == 'D'){
arr[i] = arr[i] ** 2;
}
if(v.match(/\D/) == 'T'){
arr[i] = arr[i] ** 3;
}
return arr[i];
})
//4단계. 스타상, 아차상 계산 => [ 2, 8, 27 ]
for(var i = answer.length - 1; i > -1; i--){
if(answer[i].match(/[*|#]/) == '*'){
arr[i] = arr[i] * 2;
arr[i-1] = arr[i-1] * 2;
//arr[i-2] = arr[i-2] * 2;
}
if(answer[i].match(/[*|#]/) == '#'){
arr[i] = arr[i] * -1;
}
}
//5단계. 배열의 모든 값 더해 리턴 => 37
return arr.reduce((acc,v)=> acc + v);
}
정규식과 배열 반복의 콜라보...정규식을 꽤 많이 써야해서 이 부분이 어려웠다
//1단계. 문자열에서 각 단계의 점수 쪼개기 => ["1S","2D*","3T"]
var answer = dartResult.match(/[0-9]{1,2}[S|D|T][*|#]?/g);
점수표시는 숫자+알파벳+[*|#]으로 되어있다.
이걸 정규식으로 표시하면 /[0-9]{1,2}[S|D|T][*|#]?/g이 된다.
숫자는 0부터 10까지 올 수 있으니 [0-9]{1,2}로 표시했고
알파벳은 S,D,T 중에 오니까 |로 or표시를 해줬다.
특수문자는 * 또는 #가 오는데 있을 수도 있고 없을 수도 있다는 의미의 ?를 붙여줬다.
문자열.match(정규식) 문법으로 정규식과 일치하는 문자열씩 쪼개 배열 A에 담아줬다.
//2단계. 맨 앞 점수만 가져오기 => [ '1', '2', '3' ]
var arr = answer.map(v => v.substr(0, v.match(/\D/).index));
배열 A를 반복하면서 앞의 숫자만 담은 배열을 가져오기 위해
map반복과 substr, 정규식을 사용했다.
맨 앞 자리부터 알파벳 전까지 잘라야하니 substr(0, 알파벳있는위치)를 작성해야 했다.
정규식에서 알파벳은 숫자가 아니기 때문에 /\D/로 알파벳을 찾았다. \d는 숫자, \D는 숫자가 아닌 것이다
알파벳의 위치 인덱스를 찾아 그 전까지 잘라준 값들만 새로운 배열 B에 담아줬다.
//3단계. S,D,T 계산 => [ 1, 4, 27 ]
arr = answer.map((v,i) => {
if(v.match(/\D/) == 'S'){
arr[i] = arr[i] ** 1;
}
if(v.match(/\D/) == 'D'){
arr[i] = arr[i] ** 2;
}
if(v.match(/\D/) == 'T'){
arr[i] = arr[i] ** 3;
}
return arr[i];
})
S,D,T를 계산할 때는 answer를 반복하면서 인덱스에 있는 알파벳이 무엇인지 찾고
해당 알파벳이 있다면 제곱을 해줬다.
알파벳을 찾을 때는 match(/\D/)를 사용했고 'S'라면 기준 점수만 있는 배열B의 값에 1제곱을, 'D'라면 2제곱, 'T'라면 3제곱을 해줬다.
그러면 이제 배열B는 [1,4,27]이 된다.
//4단계. 스타상, 아차상 계산 => [ 2, 8, 27 ]
for(var i = answer.length - 1; i > -1; i--){
if(answer[i].match(/[*|#]/) == '*'){
arr[i] = arr[i] * 2;
arr[i-1] = arr[i-1] * 2;
//arr[i-2] = arr[i-2] * 2;
}
if(answer[i].match(/[*|#]/) == '#'){
arr[i] = arr[i] * -1;
}
}
스타상은 i번째와 i-1번째에도 영향을 주기 때문에 반복을 돌릴 때 인덱스 값을 2에서 0으로 낮추면서 반복을 돌렸다.
특수문자 확인도 match로 확인했고 *이면 i와 i-1에 2를 곱해주고, #이면 i에만 -1을 곱해 해당 점수를 마이너스로 만들었다.
이제 배열 B는 최종 점수 [ 2, 8, 27]가 담긴 배열이 되었다.
//5단계. 배열의 모든 값 더해 리턴 => 37
return arr.reduce((acc,v)=> acc + v);
마지막으로 모든 배열의 값을 더해서 리턴해줘야 하니 reduce를 사용하면 간단하게 값을 구할 수 있다.
무작정 푸는 것보다 로직을 먼저 생각하고 푸니까 생각보다 잘 풀렸던 문제!
하지만..어렵긴 어렵다...재미는 있지만 어려워

'코딩테스트' 카테고리의 다른 글
[JS] 2019 카카오 개발자 겨울 인턴십 > 크레인 인형뽑기 게임 (0) | 2022.09.06 |
---|---|
[JS] 2019 KAKAO BLIND RECRUITMENT > 실패율 (0) | 2022.09.05 |
[JS] 탐욕법(Greedy) > 체육복 (0) | 2022.08.31 |
[JS] 연습문제 > 정수 제곱근 판별 (0) | 2022.08.29 |
[JS] 연습문제 > 두 정수 사이의 합 (0) | 2022.08.29 |