문제설명
카카오톡에 뜬 네 번째 별! 심심할 땐? 카카오톡 게임별~
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
- 다트 게임은 총 3번의 기회로 구성된다.
- 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
- 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
- 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
- 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)
- 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)
- 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
- Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
- 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.
0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.
입력 형식
"점수|보너스|[옵션]"으로 이루어진 문자열 3세트.
예) 1S2D*3T
- 점수는 0에서 10 사이의 정수이다.
- 보너스는 S, D, T 중 하나이다.
- 옵선은 *이나 # 중 하나이며, 없을 수도 있다.
출력 형식
3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다.
예) 37
입출력 예
알고리즘
주어진 문제를 풀기 앞서 알고리즘을 구성해보았습니다.
1. 변수 초기화
score 변수: 최종 점수를 저장하는 변수입니다.
answer 리스트: 점수를 계산하는 과정에서 중간 결과 값을 저장하는 동적 배열입니다. ArrayList<Integer>로 선언합니다.
temp 변수: 현재 처리 중인 숫자를 저장하는 변수입니다.
2. 숫자 처리
문자열을 순회하면서 숫자가 나올 경우 해당 숫자를 temp에 저장합니다. "10"을 처리하기 위해 "1"과 "0"이 연속해서 나올 경우 10으로 인식하도록 합니다.
3. 제곱 처리
"S", "D", "T" 문자가 나올 경우 해당 숫자를 1제곱, 2제곱, 3제곱하여 answer 리스트에 추가합니다.
제곱은 Math.pow를 사용하여 계산합니다.
4. 특수 옵션 처리
"#" 문자가 나올 경우 해당 점수를 마이너스로 만듭니다. "*" 문자가 나올 경우 해당 점수와 직전 점수를 2배로 만듭니다.
5. 최종 점수 계산
answer 리스트에 있는 점수들을 합하여 최종 점수를 계산합니다.
이 단계에 거쳐 코드를 작성해보도록 하겠습니다.
코드 설명
변수 및 리스트 초기화
int score = 0; // 최종 점수를 저장할 변수
ArrayList<Integer> answer = new ArrayList<>(); // 보너스, 옵션이 적용된 점수들을 저장할 리스트
int temp = 0; // 현재 숫자를 임시로 저장하는 변수
문자열 분석
for (int i = 0; i < dartResult.length(); i++) {
char currentChar = dartResult.charAt(i);
// ...
}
주어진 dartResult 문자열을 순회하면서 각 문자를 분석합니다.
숫자 처리
if (Character.isDigit(currentChar)) { // 숫자일 경우
if (currentChar == '1' && dartResult.charAt(i + 1) == '0') {
// 10일 경우 10으로 만들어주고 0을 건너뛰기 위해 i++
temp = 10;
i++;
} else { // 0이 아닐 경우 그대로 temp에 넣어줌.
temp = Character.getNumericValue(currentChar);
}
}
현재 문자가 숫자인 경우 해당 숫자를 temp 변수에 저장합니다.
이 때, 숫자가 10인 경우를 처리하여 temp 변수에 10을 저장하고, 다음 문자를 건너뛰기 위해 i++를 수행합니다.
isDigit() 메소드는 Java에서 문자가 숫자인지를 판별하는 역할을 합니다.
Character.getNumericValue() 메소드는 Java에서 주어진 문자의 숫자 값을 반환하는 역할을 합니다.
제곱 처리
else if (currentChar == 'S') { // 1제곱
answer.add(temp);
} else if (currentChar == 'D') { // 2제곱
answer.add((int) Math.pow(temp, 2));
} else if (currentChar == 'T') { // 3제곱
answer.add((int) Math.pow(temp, 3));
}
현재 문자가 'S', 'D', 또는 'T'인 경우 해당 제곱 값을 answer 리스트에 추가합니다.
add() 메서드는 ArrayList에 주어진 요소를 맨 뒤에 추가하는 역할을 합니다.
- 'S': 1제곱
- 'D': 2제곱
- 'T': 3제곱
옵션 처리
else if (currentChar == '#') {
answer.set(answer.size() - 1, answer.get(answer.size() - 1) * -1); // 아차상, 해당 점수 -
} else if (currentChar == '*') { // 스타상, (직전 + 해당) *2
answer.set(answer.size() - 1, answer.get(answer.size() - 1) * 2);
if (answer.size() > 1) {
answer.set(answer.size() - 2, answer.get(answer.size() - 2) * 2);
}
}
현재 문자가 '#' 또는 '*'인 경우 각각 아차상과 스타상 옵션을 처리합니다.
set() 메서드는 ArrayList에서 지정된 인덱스에 해당하는 요소를 주어진 요소로 교체하는 역할을 합니다
- '#': 해당 점수를 음수로 변경합니다.
- '*': 직전 점수와 해당 점수를 2배로 만듭니다.
- 예를 들어, 직전 점수가 5이고 현재 점수가 10인 경우, '*' 옵션을 적용하면 직전 점수와 현재 점수가 각각 10과 20이 됩니다.
점수 계산
for (int i : answer) {
score += i;
}
최종적으로 answer 리스트에 저장된 보너스와 옵션이 적용된 점수들을 합하여 최종 점수를 계산합니다.
소스코드&결과
소스 코드
import java.util.ArrayList;
public class Solution {
public int solution(String dartResult) {
int score = 0;
ArrayList<Integer> answer = new ArrayList<>();
int temp = 0; // 숫자 담을 변수
for (int i = 0; i < dartResult.length(); i++) {
char currentChar = dartResult.charAt(i);
if (Character.isDigit(currentChar)) { // 숫자일 경우
if (currentChar == '1' && dartResult.charAt(i + 1) == '0') {
// 10일 경우 10으로 만들어주고 0을 건너뛰기 위해 i++
temp = 10;
i++;
} else { // 0이 아닐 경우 그대로 temp에 넣어줌.
temp = Character.getNumericValue(currentChar);
}
} else if (currentChar == 'S') { // 1제곱
answer.add(temp);
} else if (currentChar == 'D') { // 2제곱
answer.add((int) Math.pow(temp, 2));
} else if (currentChar == 'T') { // 3제곱
answer.add((int) Math.pow(temp, 3));
} else if (currentChar == '#') {
answer.set(answer.size() - 1, answer.get(answer.size() - 1) * -1); // 아차상, 해당 점수 -
} else if (currentChar == '*') { // 스타상, (직전 + 해당) *2
answer.set(answer.size() - 1, answer.get(answer.size() - 1) * 2);
if (answer.size() > 1) {
answer.set(answer.size() - 2, answer.get(answer.size() - 2) * 2);
}
}
}
for (int i : answer) { // 보너스, 옵션 적용된 점수들 합치기
score += i;
}
return score;
}
}
실행 결과
'Coding Test > 프로그래머스' 카테고리의 다른 글
[JavaScript] 공백으로 구분하기 2 (2) | 2023.07.30 |
---|---|
[JavaScript] 최댓값과 최솟값 (0) | 2023.07.30 |
[JAVA] 기사단원의 무기 (2) | 2023.07.27 |
[JavaScript] 문자열 내 p와 y의 개수 (2) | 2023.07.25 |
[JavaScript] 음양 더하기 (2) | 2023.07.24 |