Notice
Recent Posts
Recent Comments
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Today
Total
관리 메뉴

차차로그

[JS] 2018 KAKAO BLIND RECRUITMENT[1차] > 다트 게임 본문

코딩테스트

[JS] 2018 KAKAO BLIND RECRUITMENT[1차] > 다트 게임

차차한 2022. 9. 2. 08:57

드디어 푼 다트게임 코테!!

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를 사용하면 간단하게 값을 구할 수 있다.

 

무작정 푸는 것보다 로직을 먼저 생각하고 푸니까 생각보다 잘 풀렸던 문제!

하지만..어렵긴 어렵다...재미는 있지만 어려워

 

Comments