본문 바로가기
알고리즘 문제 풀이/프로그래머스

[1차] 다트게임

by 성건희 2022. 7. 17.
반응형

본 풀이는 java 언어를 사용하였습니다.
문제 보러가기

풀이

문자열을 세트(점수, 보너스, 옵션) 별로 구분하면 문제를 쉽게 풀 수 있다.
아래와 같이 세트별로 나누는 toSplitText 메서드를 추가했다.

private String[] toSplitText(String dartResult) {
    StringBuilder sb = new StringBuilder();
    sb.append(dartResult.charAt(0));
    int startIndex = 1;
    // 숫자가 10 인경우
    if (isNumber(dartResult.charAt(1))) {
        sb.append(dartResult.charAt(1));
        startIndex = 2;
    }
    sb.append(" ");
    for (int i = startIndex; i < dartResult.length(); i++) {
        char word = dartResult.charAt(i);
        if (isNumber(word)) {
            sb.append("/");
            sb.append(word);
            if (i + 1 < dartResult.length() && isNumber(dartResult.charAt(i + 1))) {
                sb.append(dartResult.charAt(i + 1));
                i++;
            }
        } else {
            sb.append(word);
        }
        sb.append(" ");
    }
    return sb.toString().split("/");
}

split 시 문자열 셋트별로 쪼개기 위해서 숫자 앞에 / 를 추가해서 풀었다.
맨 처음에는 무조건 숫자이므로, StringBuilder 에 넣어주고 숫자가 10 일 수 있으므로 해당 부분을 체크한다.
점수, 보너스, 옵션 각각은 공란(" ") 으로 구분하였다.
만약 dartResult 값이 1S2D*3T 로 들어온다면, return 값은 [1 S], [2 D *], [3 T] 가 된다.

점수는 return 값의 개수로 각각 넣어줄 예정이므로 아래와 같이 초기화한다.

String[] dartResults = toSplitText(dartResult);
int[] sums = new int[dartResults.length];
for (int i = 0; i < dartResults.length; i++) {
    String[] words = dartResults[i].split(" ");
    sums[i] = calculate(words);
    // 옵션이 있다면
    if (words.length == 3) {
        if (words[2].equals("*")) {
            sums[i] = sums[i] * 2;
            if (i != 0) {
                sums[i - 1] = sums[i - 1] * 2;
            }
            continue;
        }
        if (words[2].equals("#")) {
            sums[i] = -sums[i];
            continue;
        }
        throw new IllegalArgumentException("존재하지 않는 옵션입니다.");
    }
}

calculate 메서드에서 해당 문자열의 값을 계산해서 넣어주고, 옵션이 있는 경우 해당 값을 변경시킨다.

  • * 인 경우, 자신과 이전값을 X 2 배
  • # 인 경우, 자신을 음수로 변경

calculate 메서드의 계산식은 아래와 같다.

private int calculate(String[] words) {
    int score = Integer.parseInt(words[0]);
    String bonus = words[1];
    if (bonus.equals("S")) {
        return score;
    }
    if (bonus.equals("D")) {
        return (int) Math.pow(score, 2);
    }
    if (bonus.equals("T")) {
        return (int) Math.pow(score, 3);
    }
    throw new IllegalArgumentException("존재하지 않는 보너스입니다.");
}

그 후 결과값은 sum 배열을 모두 더하기만 하면 끝이다.

return Arrays.stream(sums)
             .sum();

코드

import java.util.Arrays;

public class Solution {

    public int solution(String dartResult) {
        String[] dartResults = toSplitText(dartResult);
        int[] sums = new int[dartResults.length];

        for (int i = 0; i < dartResults.length; i++) {
            String[] words = dartResults[i].split(" ");
            sums[i] = calculate(words);
            if (words.length == 3) {
                if (words[2].equals("*")) {
                    sums[i] = sums[i] * 2;
                    if (i != 0) {
                        sums[i - 1] = sums[i - 1] * 2;
                    }
                    continue;
                }
                if (words[2].equals("#")) {
                    sums[i] = -sums[i];
                    continue;
                }
                throw new IllegalArgumentException("존재하지 않는 옵션입니다.");
            }
        }

        return Arrays.stream(sums)
                     .sum();
    }

    private int calculate(String[] words) {
        int score = Integer.parseInt(words[0]);
        String bonus = words[1];
        if (bonus.equals("S")) {
            return score;
        }
        if (bonus.equals("D")) {
            return (int) Math.pow(score, 2);
        }
        if (bonus.equals("T")) {
            return (int) Math.pow(score, 3);
        }
        throw new IllegalArgumentException("존재하지 않는 보너스입니다.");
    }

    private String[] toSplitText(String dartResult) {
        StringBuilder sb = new StringBuilder();
        sb.append(dartResult.charAt(0));
        int startIndex = 1;
        if (isNumber(dartResult.charAt(1))) {
            sb.append(dartResult.charAt(1));
            startIndex = 2;
        }
        sb.append(" ");
        for (int i = startIndex; i < dartResult.length(); i++) {
            char word = dartResult.charAt(i);
            if (isNumber(word)) {
                sb.append("/");
                sb.append(word);
                if (i + 1 < dartResult.length() && isNumber(dartResult.charAt(i + 1))) {
                    sb.append(dartResult.charAt(i + 1));
                    i++;
                }
            } else {
                sb.append(word);
            }
            sb.append(" ");
        }
        return sb.toString().split("/");
    }

    private boolean isNumber(char word) {
        return 48 <= word && word <= 57;
    }
}

회고

dartResult 문자를 어떻게 점수, 옵션, 보너스로 구분할 지에 가장 생각을 많이 했던 것 같다.
점수에 따라 나눌수 있다면 그 다음부터는 쉽게 문제를 풀 수 있었다.

반응형

댓글