[프로그래머스] Lv.1 다트 게임 (JavaScript)

혜린·2022년 5월 25일
0
post-thumbnail

🔐 다트 게임


문제

카카오톡에 뜬 네 번째 별! 심심할 땐? 카카오톡 게임별~

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

  1. 다트 게임은 총 3번의 기회로 구성된다.
  2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
  3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
  4. 옵션으로 스타상* , 아차상#이 존재하며 스타상* 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상# 당첨 시 해당 점수는 마이너스된다.
  5. 스타상*은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상*의 점수만 2배가 된다.
  6. 스타상*의 효과는 다른 스타상*의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상* 점수는 4배가 된다.
  7. 스타상*의 효과는 아차상#의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상#의 점수는 -2배가 된다.
  8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
  9. 스타상*, 아차상#은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

입출력 예제



🔑 풀이


나의 풀이

  1. 문자열의 보너스와 옵션 S, D, T, *, #
    ◾ dartResult를 크게 S, D, T, *, #인 경우로 나누어 조건을 설정한다.
    ◾ 빈 배열 sum을 선언해주어 점수를 이 빈 배열 안에 누적해준 뒤, return할 때 총합을 구해줄 것이다.

  2. 문자열의 점수는 한 자릿수인가 두 자릿수인가
    S, D, T인 경우는 그 안에서는 또 한 자릿수일 때와 두 자릿수일 때로 경우가 나뉜다.
    ◾ 해당 문자 앞에 1부터 9까지의 한 자릿수가 나오면, 해당 숫자에 1제곱(S), 2제곱(D), 3제곱(T)으로 계산한다.
    ◾ 두 자릿수인 경우는 10밖에 없으므로 10에 1제곱(S), 2제곱(D), 3제곱(T)하여 계산한다.

  3. 스타상과 아차상을 계산하기 위해 sum의 index를 구함
    ◾ 스타상과 아차상은 이전 점수들을 필요로하므로, sum 배열의 index를 알아야 한다. 하지만, 10과 같이 두 자릿수가 있을 경우 index를 정확히 파악하기 어렵다고 생각하여 sum에 점수를 push해줄 때마다 index를 하나씩 증가시켜 sum의 index를 구해주었다.
function solution(dartResult) {
    let sum = [];
    let index = 0; 
    
    for(let i = 0; i < dartResult.length; i++){
        if(dartResult[i] === "S"){
            if((dartResult[i-2] === "1") && (dartResult[i-1] === "0")){ 
                sum.push(10**1);
            } else {
                sum.push(dartResult[i-1]**1);
            }
            index++;
        } else if (dartResult[i] === "D"){
            if((dartResult[i-2] === "1") && (dartResult[i-1] === "0")){  
                sum.push(10**2);
            } else {
                sum.push(dartResult[i-1]**2);
            }
            index++;
        } else if (dartResult[i] === "T"){
            if((dartResult[i-2] === "1") && (dartResult[i-1] === "0")){ 
                sum.push(10**3);
            } else {
                sum.push(dartResult[i-1]**3);
            }
            index++;
        } else if (dartResult[i] === "*"){
            sum[index - 1] *= 2;
            sum[index - 2] *= 2;
        } else if (dartResult[i] === "#"){
            sum[index - 1] *= (-1);
        } 
    }
    
    return sum.reduce((acc, curr) => acc + curr, 0);
}

리팩토링

  1. 보너스인 S, D, T마다 조건을 나누어주었던 점수가 10인 경우를 따로 빼주어 중복을 줄였다.
  2. sum의 index를 각 조건 별로 따로 구해줄 필요 없이 sum의 길이로 해결가능했다.
function solution(dartResult) {
    let sum = [];

    for(let i = 0; i < dartResult.length; i++){
        let sumLength = sum.length;
        if((dartResult[i-2] === "1") && (dartResult[i-1] === "0")){
            if(dartResult[i] === "S") sum.push(10**1);
            if(dartResult[i] === "D") sum.push(10**2);
            if(dartResult[i] === "T") sum.push(10**3);
        }
        if(dartResult[i] === "S"){
            sum.push(dartResult[i-1]**1);
        } else if (dartResult[i] === "D"){
            sum.push(dartResult[i-1]**2);
        } else if (dartResult[i] === "T"){
            sum.push(dartResult[i-1]**3);
        } else if (dartResult[i] === "*"){
            sum[sumLength - 1] *= 2;
            sum[sumLength - 2] *= 2;
        } else if (dartResult[i] === "#"){
            sum[sumLength - 1] *= (-1);
        } 
    }
  
    return sum.reduce((acc, curr) => acc + curr, 0);
}



🔗 링크


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

profile
FE Developer

0개의 댓글