[프로그래머스] (C++) 다트 게임 <2018 KAKAO BLIND RECRUITMENT>

winluck·2023년 7월 2일
1

https://school.programmers.co.kr/learn/courses/30/lessons/17682

문제

0~10의 정수, 문자 S, D, T, #, * 5가지에 따른 점수를 계산한다.

입출력

결과를 보면 알 수 있듯이 간단한 문자열 문제이다. (2022~2023 코테 난이도랑 비교하면 굉장히 평화롭다..)

문자열을 순회하면서 다음과 같은 경우를 고민해야 한다.

  • S, D, T일 때: 1제곱, 2제곱, 3제곱 처리
  • #일 때: 현재 차례의 점수에 -1을 곱한다.
  • *일 때: 현재 차례의 점수와, 만약 직전 차례가 있다면 직전 차례의 점수도 2배로 증가시킨다. 중첩될 수 있음에 유의하자.

시행착오

문자열을 순회하면서 특수기호에 따라 바로바로 현재 점수와 직전 점수를 내부 for문 및 배열로 역추적하면서 해결하려 했으나 복잡해지는 것 같아서 정수/기호 파싱과 점수 계산을 분리하였다. 물론 이 문제는 입력이 복잡하지 않기에 충분히 그렇게 해결할 수 있겠지만, 작성하는 입장에서 명확하게 상황을 분리하는 게 더 나아 보였다.


먼저 문자열을 순회하면서 점수와 기호를 분리한다. 문자열을 stoi를 통해 정수로 변환해주었다.

다음으로, #와 *의 위치에 따라 이에 대응하는 점수 배열 값을 바꾸어주면 끝이다.

  • #의 경우 현재 점수를 음수로 바꾼다.
  • *의 경우 현재 점수를 2배로, 만약 직전 점수가 존재한다면 그것도 2배로 늘린다.

소스 코드

#include <string>
#include <algorithm>

using namespace std;

int solution(string dartResult) {
    int answer = 0;
    int cnt = 0; // 차례
    int score[3]; // 점수
    char special[3]; // 옵션
    string s = ""; // 파싱을 위한 문자열
    
    for(int i=0; i<dartResult.size(); i++){
        if(dartResult[i] == 'S'){
            score[cnt] = stoi(s);
            cnt++;
            s = "";
            continue;
        } else if(dartResult[i] == 'D'){
            score[cnt] = (stoi(s) * stoi(s));
            cnt++;
            s = "";
            continue;
        } else if(dartResult[i] == 'T'){
            score[cnt]= (stoi(s) * stoi(s) * stoi(s));
            cnt++;
            s = "";
            continue;
        } // S, D, T 조건에 따라 stoi로 정수로 변환하여 점수 배열에 추가
        
        if(dartResult[i] == '#'){
            int pos = cnt - 1;
            special[pos] = '#';
            continue;
        } else if(dartResult[i] == '*'){
            int pos = cnt - 1;
            special[pos] = '*';
            continue;
        } // 특수기호 배열에 기호 추가
        s += dartResult[i];
    }
    
    for(int i=0; i<3; i++){ // 점수 계산
        if(special[i] == '#'){
            score[i] = score[i] * -1; // 현재 점수 * -1로 변환
        } else if(special[i] == '*'){
            score[i] = score[i] * 2; // 현재 점수 2배로
            if(i-1 >= 0){
                score[i-1] = score[i-1] * 2; // 직전 점수 2배로
            }
        }
    }

    answer += score[0] + score[1] + score[2];
    return answer;
}

교훈

  • 풀 수 있는 쉬운 문제를 정확하고 빠르게 푸는 것이 중요하다.
  • 문자열 문제가 자주 나오니까 소홀히 하지 말자.
  • cout을 통해 파싱이 제대로 이루어졌는지 파악하는 습관을 갖자.
profile
Discover Tomorrow

0개의 댓글