카카오 기출 뽀개기 이번에 푼 문제는 카카오 2018 블라인드 채용 - 다트게임이다.
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.
"점수|보너스|[옵션]"으로 이루어진 문자열 3세트.
예) 1S2D*3T
3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다.
예) 37
예제 | dartResult | answer | 설명 |
---|---|---|---|
1 | 1S2D*3T | 37 | 1^1 2 + 2^2 2 + 3^3 |
2 | 1D2S#10S | 9 | 1^2 + 2^1 * (-1) + 10^1 |
3 | 1D2S0T | 3 | 1^2 + 2^1 + 0^3 |
4 | 1S2T3S | 23 | 1^1 2 2 + 2^3 * 2 + 3^1 |
5 | 1D#2S*3S | 5 | 1^2 (-1) 2 + 2^1 * 2 + 3^1 |
6 | 1T2D3D# | -4 | 1^3 + 2^2 + 3^2 * (-1) |
7 | 1D2S3T* | 59 | 1^2 + 2^1 2 + 3^3 2 |
정규식을 이용해서 문제를 풀었다. 0-10까지라서 숫자가 1자리일수도 2자리일수도 있기에 이게 깔끔하겠다 싶었다.
또한 점수를 관리할 Score 클래스를 만들어 사용하였다. 점수와 op1까지 반영된 값이 저장될 score와 op2는 이전 원소에도 영향을 줄 수 있는 값이기 때문에 추후에 한 번에 반영하기 위해서 따로 저장해두었다. 또한 op2에 따라서 수행해야하는 두 배, 마이너스를 해주는 함수도 정의해두었다.
이제 입력으로 받은 스트링과 패턴 두 개로 score와 옵션들을 뽑아냈다. 옵션에는 첫자리는 op1이고, op2는 있을 수도 없을 수도 있다. 정규식을 통해 뽑아낸 문자열들을 이용하여 Score 객체를 만들었고 이를 스택에 저장해주었다.
스택에 저장한 이유는 op2가 앞의 값에 영향을 줄 수 있기 때문에 가장 마지막에 넣은 값부터 그 것을 판단해서 반영해야하고, 직전값도 peek으로 바로 접근할 수 있기 때문이다. 그렇게 stack에 저장된 값들을 하나씩 뽑아내면서 점수를 반영해서 최종적으로 반환해주었다.
개인적으로 이번 코드가 깔끔하고 가독성도 나쁘지 않아서 코드를 보면 바로 이해할 수 있을 것 같다 ! 혹 나중에 op1, op2가 다양해지면 character에 따른 제곱수 숫자나 함수를 매칭해두고 사용하면 될 거 같다. map이나 뭐 등등..
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Solution {
public static class Score{
private double score;
private char op2 = ' ';
Score(String score, String op){
double pow;
if(op.charAt(0) == 'S') pow = 1;
else if(op.charAt(0) == 'D') pow = 2;
else pow = 3;
this.score = Math.pow(Double.parseDouble(score), pow);
if(op.length() > 1) op2 = op.charAt(1);
}
public void makeDouble(){
this.score *= 2;
}
public void makeMinus(){
this.score *= -1;
}
}
public int solution(String dartResult) {
int answer = 0;
Pattern patternScore = Pattern.compile("[0-9]{1,2}");
Pattern patternOp = Pattern.compile("[SDT][*#]?");
Matcher matcherScore = patternScore.matcher(dartResult);
Matcher matcherOp = patternOp.matcher(dartResult);
Stack<Score> scores = new Stack<>();
while(matcherScore.find() && matcherOp.find()){
scores.push(new Score(matcherScore.group(), matcherOp.group()));
}
Score current;
while(!scores.isEmpty()){
current = scores.pop();
if(current.op2 == '*'){
current.makeDouble();
if(!scores.isEmpty()) scores.peek().makeDouble();
}
else if(current.op2 == '#') current.makeMinus();
answer += current.score;
}
return answer;
}
}