치악산 복숭아

[프로그래머스] 다트 게임 - Javascript 본문

PS:0

[프로그래머스] 다트 게임 - Javascript

Juliie 2020. 9. 17. 01:24

링크

programmers.co.kr/learn/courses/30/lessons/17682

 

코딩테스트 연습 - [1차] 다트 게임

 

programmers.co.kr


문제 설명

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

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

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

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


문제 풀이

1) 코드 설명

 (1) for문을 이용해 dartResult의 길이만큼 각 character를 검사하도록 한다.

 (2) 검사하려는 character가 0~9 사이의 숫자일 경우 다음 숫자가 0인지 한번 더 검사한다(10인지 확인하기 위해서)

 (3) 10인 경우 temp에 10을 저장한 뒤 i를 높여준다(0 부분을 건너뛰기 위해서)

 (4) 0이 아닌경우 해당 숫자를 그대로 temp에 저장한다.

 (5) 숫자가 아닌 'S', 'D', 'T'인 경우 해당 값을 answer에 push한다.

 (6) '#'일 경우 직전 값에 -1을 곱해준다.

 (7) '*'일 경우 직전 값과 그 전 값을 2배로 만들어야 하기 때문에 해당 값에 2를 곱해준다.

 (8) answer에 push 됐던 값들을 숫자형으로 변환해서 모두 더해준다.

 

2) 코드

function solution(dartResult) {
    var num = 0;
    var answer = [];
    var temp = 0;
    for(var i = 0; i < dartResult.length; i++) {
        if(dartResult[i] >= 0 && dartResult[i] <= 9) {
            if(dartResult[i] == 1 && dartResult[i+1] == 0) {
                temp = 10;
                i++;
            }
            else {
                temp = dartResult[i];
            }
        }
        else if(dartResult[i] === 'S') {
            answer.push(temp);
        }
        else if(dartResult[i] === 'D') {
            answer.push(Math.pow(temp, 2));
        }
        else if(dartResult[i] === 'T'){
            answer.push(Math.pow(temp, 3));
        }
        else if(dartResult[i] == '#') {
           answer[answer.length-1]*=-1;
        }
        else if(dartResult[i] == '*') {
            answer[answer.length-1]*=2;
            answer[answer.length-2]*=2;
        }
    }
    for(var i = 0; i < answer.length; i++) {
        num +=Number(answer[i]);
    }
    return num;
}

3) ⬇️수정한 코드 및 코드 설명⬇️

  • arr : 점수 저장용 배열
  • point: arr의 현재 인덱스 위치, 처음엔 -1로 초기화

① dartResult의 i번째 문자가 숫자인지 그 외의 문자(알파벳, 특수문자)인지 검사

  • 숫자일 경우
    • point를 1 증가시켜 arr의 새로운 위치를 가리킬 수 있도록 한다
    • 숫자가 10(두자릿수)일 경우 한번에 arr[point]에 10을 넣고, 다음 i는 넘어가기 위해서 i++(다음 i는 0이기 때문)하고 끝내기
    • 숫자가 0~9(한자릿수)일 경우 그 숫자를 넣는다
  • 그 외의 문자일 경우
    • D: 해당 숫자를 2제곱
    • T: 해당 숫자를 3제곱 (S는 1제곱이기 때문에 따로 조건 추가 안했음)
    • *: 현재 인덱스와 직전 인덱스의 arr에 *2
    • #: 현재 점수 마이너스 -> *(-1)해줌

② arr의 모든 값을 reduce로 더하고 return

//210627
function solution(dartResult) {
    let arr = [0,0,0];
    let point = -1; 
    for(var i = 0 ; i < dartResult.length; i++) {
        if(Number.isInteger(dartResult[i]*1)) {
            point++;
            if (dartResult[i] == '1' && dartResult[i+1] == '0') {
                arr[point]+=10;
                i++;
                continue;
            }
            else arr[point]+=dartResult[i]*1;
        }
        else {
            if (dartResult[i] == 'D') arr[point]**=2;
            else if (dartResult[i] == 'T') arr[point]**=3;
            else if (dartResult[i] == '*') {
                arr[point]*=2;
                arr[point-1]*=2;
            }
            else if (dartResult[i] == '#') arr[point]*=(-1);
        }
    }
    return arr.reduce((a, b) => a+b);
}

 

정리 하고나니까 달라진게 별로 없음🤔

맨처음엔 정규식이랑 split써서 풀려고 했는데 계속 정규식 조건에 맞는 문자가 없어져서 포기했는데 split 대신 match를 쓰면 된다고 한다,,,눈물

Comments