알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

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

 

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

 

programmers.co.kr


Think🤔

문제 의도 파악하기.

 

다트 게임 기회 총 3번.

각 기회 0~10점.

S 1제곱, D 2제곱, T 3제곱 영역 존재.

옵션 스타상 * (해당 점수 , 그 전 점수)X2

옵션 아차상 # -해당점수

 

스타상 처음에 나올 시 첫 번째만 2배

스타상 점수 중첩될 시 4배가 될 수 있음.

 

스타상 , 아차상 중첩시 -2배

 

총 3번의 기회에서 얻은 값을 반환한다.

 

1. 방법

첫 번째 떠오른 방법은.. 반복문을 돌리고, 숫자가 나오면 if문을 이용해서 뒤에 문자를 제곱해주고 , 

tmp를 이용해서 옵션이 있을 경우 해당 인덱스 값을 넣어주고, 다음에도 나왔을 시, 그 전 위치도 옵션을 이용해 주는 방법이다.

>> 이 방법은 0~10점까지 존재하는데 10점이 나왔을 경우 '0'도 숫자로 인식해서 오버 스택이 발생할 수 있다.

 

보안 : 1인 경우(다음 인덱스가 숫자일 경우 10으로 취급)

 

2. 방법

두 번째 방법은.. 숫자를 먼저 분리를 시켜줘야 한다 어떻게 문자열을 3세트로 구분해줄까?

1S2D*3T

9S10D10T

옵션이 있어서 구분하는 방법이 1.방법 말고는 떠오르지 않는다. 일단 1방법을 이용해서 코드를 짜본다.

 

package program22y02;

import java.util.Arrays;

public class dart {
	public static void main(String[] args) {
		
		String dartResult = "1D2S#10S";
		
		// 48~57 0~9임
		
        int dRleng = dartResult.length(); // 다트 문자열 길이        
        int[] round = new int[3]; // 라운드 총 3
        
        int rNum = 0; // 현재 라운드
        for(int i=0; i<dRleng; i++){
            if((char)dartResult.charAt(i) > 47 && (char)dartResult.charAt(i) < 58){ // 0 ~ 9
            	System.out.println(dartResult.charAt(i));
                if(dartResult.charAt(i) == (char)49 && dartResult.charAt(i+1) == (char)48){ // 10인 경우
                    round[rNum] = i;
                    i++; // 다음 i도 넘김
                } else { // 10아닐때
                    round[rNum] = i;
                }
                System.out.println("i : " + i + ", rNum : " + rNum + ", dartResult.charAt(i) : " + dartResult.charAt(i));
                rNum++;
                System.out.println("ArrayIndex : " + i);
            } 
        }
        
        System.out.println(Arrays.toString(round));
	}
}

아스키코드를 이용해서 먼저 숫자들의 위치를 배열을 만들어서 집어 넣어 줬다.

 

처음 방법에서는 하나의 반복문으로 처리하려고 했지만, 그러면 안에 if문이 너무 많이 들어가게 돼서

일단은 각 라운드의 값을 배열로 받았다.

 

이 배열을 가지고 , 다음 배열 전까지 반복문을 돌고 그 값을 계산해준다.

 

int answer=0;
		// 48~57 0~9임
		
        int dRleng = dartResult.length(); // 다트 문자열 길이        
        int[] round = new int[4]; // 라운드 총 3 , 마지막에 문자열 마지막 길이를 넣어준다.
        int[] roundScore = new int[3]; // 라운드 스코어
        
        int rNum = 0; // 현재 라운드
        for(int i=0; i<dRleng; i++){
            if(dartResult.charAt(i) > 47 && dartResult.charAt(i) < 58){ // 0 ~ 9
                if(dartResult.charAt(i) == (char)49 && dartResult.charAt(i+1) == (char)48){ // 10인 경우
                    round[rNum] = i;
                    i++;
                } else { // 10아닐때
                    round[rNum] = i;
                }
                rNum++;
            } 
        }
        round[3] = dRleng;
        
        
        // 총 3라운드 진행
        for(int i=0; i<3; i++) {
        	int tmp = 0; // 계산을 하기 위한 tmp
        	for(int j=round[i]; j<round[i+1]; j++) {
        		int acha = 0; // 아차상 구하기
        		
        		if(dartResult.charAt(j) > 47 && dartResult.charAt(j) < 58) { // 숫자면 ~
        			if(dartResult.charAt(j) == (char)49 && dartResult.charAt(j+1) == (char)48) { // 10이면
        				tmp=10;
        				j++;
        			}else { // 0~9이면
        				tmp = dartResult.charAt(j) - '0';
        				System.out.println(tmp);
        			}
        		}else if(dartResult.charAt(j) == 'D') {
        			tmp = tmp*tmp;
        		} else if(dartResult.charAt(j) == 'T') {
        			tmp = tmp*tmp*tmp;
        		} else if(dartResult.charAt(j) == '*') {
        			if(i > 0) {
        				roundScore[i-1] = roundScore[i-1] * 2;
        			}
        			tmp = tmp*2;
        		} else if(dartResult.charAt(j) == '#') {
        			if(acha > 0) {
        				roundScore[acha] = roundScore[acha] * -1;
        			}
        			tmp = tmp * -1;
        			acha++; // 아차상 +1
        		}
        	}
        	roundScore[i] = tmp;
        }
        
        for(int i=0; i<3; i++) {
        	answer+=roundScore[i];
        }

일단 숫자별로 잘라주었다.

10인 경우를 if문해서 한번 더 처리하고 그 다음인덱스를 넘겨주기 위해서 i++로 처리 했다.

라운드 스코어를 총 4개를 주고, 마지막 라운드에는 dataResult의 마지막인덱스 값을 넣어줘서

 

반복문을 이용해서 

숫자부터 tmp에서 넣고

S인 경우는 넣지 않았음(어차피 1이기때문)

D인 경우 제곱 Math를 사용해도 되나, tmp*tmp도 가능

T인 경우도 마찬가지로 tmp*tmp*tmp 세제곱을 넣어주고,

 

int acha = 0; 

만약 라운드가 1라운드가 아닌, 2,3라운드 일 경우 '*'이 나온 더블 스코어(곱하기 2)를 해주고,

만약에 아차상(#)이 나온경우 마이너스를 해주는데, 전에 아차상이 존재한 값에는 -1를 또 곱해줘야 한다.

 

그렇게 나온 3개의 라운드를 answer에 다 더해주면 값이 나온다.


Solution✍

처음에는 라운드를 3개를 주려고 했지만, 마지막 인덱스값이 필요했기 때문에 round를 총 4개를 넣었다.


Review🤩

디버그를 찍으면서 중간에 .charAt부분에서 좀 헤맸지만 (char)48은 0인데 1로 해석했음..

디버그의 중요성을 다시 한번 느꼈다!!


 

+ Recent posts