본문 바로가기

알고리즘 풀이/프로그래머스

[프로그래머스] 다트 게임 / 2018 KAKAO BLIND RECRUITMENT(1차) - JAVA

🔗 문제 링크

[프로그래머스] 다트 게임 / 2018 KAKAO BLIND RECRUITMENT(1차)

 

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

 

programmers.co.kr

 

📝 풀이 과정

다트 게임의 결과가 일정한 패턴을 가진 String로 들어오게 된다.
String을 하나씩 끊어가며 처리하는 방법도 있겠지만, 숫자의 경우 10이 들어오게 되면 처리가 불편해지기 때문에 PatternMatcher class를 사용하기로 했다. (참고 : [Java] Pattern, Matcher Class로 정규식 활용하기)

 

 

Pattern pattern = Pattern.compile("([0-9]+)([SDT])([*#]?)");
Matcher matcher = pattern.matcher(dartResult);

다트 게임의 결과는 (숫자 + S/D/T + [*/#])의 형태로 각 라운드 별로 구성되어 있기 때문에 이를 기준으로 패턴을 생성해주었다. 이후, Matcher.find()를 통해 다음 라운드의 결과가 있는지 확인하고 Matcher.group()을 통해 해당 라운드의 결과 String을 받아와 하나씩 잘라 값을 계산해 주었다.

 

int tmp = Integer.parseInt(matcher.group(1));

tmp변수를 통해 현재 라운드의 값을 누적한다. matcher의 group()함수를 활용해 첫 번째 그룹의 값인 점수를 가져와 파싱 해준다.

 

 

switch (matcher.group(2)) {
  case "D":
    tmp *= tmp;
    break;
  case "T":
    tmp *= tmp * tmp;
}

두 번째 그룹의 값을 가져와 보너스 점수를 계산한다. S일 경우는 기존 값과 동일하기 때문에 따로 처리하지 않았다.

 

 

switch (matcher.group(3)) {
  case "*":
    if (!score.isEmpty())
      score.push(score.pop() * 2);
    tmp *= 2;
    break;
  case "#":
    tmp *= -1;
    break;
}

이후, 세 번째 그룹의 값을 가져와 스타상*이나 아차상#인 경우를 처리해주었다. 이때, score의 누적을 바로 계산하지 않고 stack으로 모아두었는데 만약 스타상이 나올 경우 앞의 점수까지 두배 처리해주어야 하기 때문에 stack.pop을 통해 값을 꺼내온 다음 다시 2배 한 값을 push한다.

 

 

마지막으로 스택에 있는 모든 점수를 더해 출력해주면 결괏값이 나오게 된다.

 

💻 코드

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Solution {
    public int solution(String dartResult) {
        Pattern pattern = Pattern.compile("([0-9]+)([SDT])([*#]?)");
        Matcher matcher = pattern.matcher(dartResult);

        Deque<Integer> score = new ArrayDeque<>();
        while (matcher.find()) {
            int tmp = Integer.parseInt(matcher.group(1));

            switch (matcher.group(2)) {
                case "D":
                    tmp *= tmp;
                    break;
                case "T":
                    tmp *= tmp * tmp;
            }

            switch (matcher.group(3)) {
                case "*":
                    if (!score.isEmpty())
                        score.push(score.pop() * 2);
                    tmp *= 2;
                    break;
                case "#":
                    tmp *= -1;
                    break;
            }
            score.push(tmp);
        }

        int ans = 0;
        while (!score.isEmpty())
            ans += score.pop();

        return ans;
    }
}