1. 문제
programmers.co.kr/learn/courses/30/lessons/17682
문제 설명
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
- 다트 게임은 총 3번의 기회로 구성된다.
- 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
- 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 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
입출력 예
예제 | 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 | 1S*2T*3S | 23 | (1^2 * -1 * 2) + (2^1 * 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) |
2. 어떻게 풀까?
- 문제에서 다트는 총 3번 던지니까 String의
split()
메서드를 이용해서 점수와 보너스,옵션을 분리할 수 있을 것이다.- 근데 분리할 때, empty string ("")이 생길 수 있으니 유의해야할듯.
- 그래서 보너스 문자에 따라 점수에 2제곱, 3제곱, *2, *-1 등을 해주어 배열에 저장하고 다 더해주면 되겠다.
- 문자열을 반복문 돌며 계산해줘도 될거라 생각했는데 10점이 변수가되기 때문에 그냥 분리하는게 낫겠다.
3. 코드
TDD 연습을 위해 1번 테스트 👉 실제 코드 작성 👉 리팩토링 👉 다음 테스트 👉 실제 코드 작성 👉 리팩토링 ... 순서로 계속 살을 붙여나갔다.
테스트 코드
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import org.junit.Test;
public class SolutionTest {
@Test
public void test1() {
assertThat(new Solution().solution("1S2D*3T"), is(37));
}
@Test
public void test2() {
assertThat(new Solution().solution("102S#10S"), is(9));
}
@Test
public void test3() {
assertThat(new Solution().solution("1D2S0T"), is(3));
}
@Test
public void test4() {
assertThat(new Solution().solution("1S*2T*3S"), is(23));
}
@Test
public void test5() {
assertThat(new Solution().solution("1D#2S*3S"), is(5));
}
@Test
public void test6() {
assertThat(new Solution().solution("1T2D3D#"), is(-4));
}
@Test
public void test7() {
assertThat(new Solution().solution("1D2S3T*"), is(59));
}
}
실제 코드
import java.util.Arrays;
public class Solution {
public int solution(String dartResult) {
int[] scores = getScores(dartResult);
String[] bonus = getBonus(dartResult);
return getSumOfScore(scores, bonus);
}
private int getSumOfScore(int[] scores, String[] bonus) {
int[] result = new int[3];
for (int i = 0; i < bonus.length; i++) {
int score = scores[i];
if (bonus[i].contains("T")) {
score = (int) Math.pow(score, 3);
} else if (bonus[i].contains("D")) {
score = (int) Math.pow(score, 2);
}
if (bonus[i].contains("*")) {
score *= 2;
if (i != 0) {
result[i - 1] *= 2;
}
} else if (bonus[i].contains("#")) {
score *= -1;
}
result[i] = score;
}
return Arrays.stream(result).sum();
}
private String[] getBonus(String dartResult) {
String[] bonus = new String[3];
String[] bonusSplit = dartResult.split("\\d");
int index = 0;
for (int i = 0; i < bonusSplit.length; i++) {
if (!bonusSplit[i].equals("")) {
bonus[index++] = bonusSplit[i];
}
}
return bonus;
}
private int[] getScores(String dartResult) {
int[] scores = new int[3];
String[] scoresSplit = dartResult.split("[SDT*#]");
int index = 0;
for (String score : scoresSplit) {
if (!score.equals("")) {
scores[index++] = Integer.parseInt(score);
}
}
return scores;
}
}
getBonus()
와getScores()
에서 emptyString("")을 제외하고 점수, 보너스를 각 배열에 담았다.- 그 배열들을 이용해서
getSumOfScore()
메서드를 통해 총 점수를 계산하고 리턴했다.
4. 느낀점
- 카카오 코테 문제가 비교적 어렵다고해도 level1 수준의 문제는 간단하게 풀 수 있다. 시간도 약 20~30분정도? 더 줄이면 좋겠지만, level1을 다 풀 수 있는걸로 만족은 한다.
- level2 이상은 좀 많이 어렵긴한데 적어도 level1 수준의 문제는 확실히 다 풀 수 있도록 해야겠다.
'Coding Test > Programmers' 카테고리의 다른 글
프로그래머스 - 프렌즈 4블록 (12/22) (java) (1) | 2020.12.22 |
---|---|
프로그래머스 - 뉴스 클러스터링 (12/10) (java) (0) | 2020.12.10 |
프로그래머스 - 키패드 누르기 (11/18) (java) (1) | 2020.11.18 |
프로그래머스 - 비밀지도(11/11) (java) (0) | 2020.11.11 |
프로그래머스 - 수식 최대화(10/30) (java) (1) | 2020.10.30 |