알고리즘 풀이 방법입니다.
문제(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로 해석했음..
디버그의 중요성을 다시 한번 느꼈다!!
'Algorithm' 카테고리의 다른 글
[인프런] 아나그램(해쉬) (0) | 2022.02.27 |
---|---|
[백준] 일곱 난쟁이 (0) | 2022.02.27 |
[프로그래머스] 두 정수 사이의 합 (0) | 2022.02.24 |
[프로그래머스] SQL 2LEVEL(고양이와 개는 몇 마리, 루시와 엘라 찾기, 최솟값 구하기) (0) | 2022.02.11 |
[프로그래머스] SQL 1LEVEL 문제 모음 (0) | 2022.02.11 |