문제링크
https://school.programmers.co.kr/learn/courses/30/lessons/17682
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 핵심
- 다트 게임은 총 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, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.
알고리즘
1.숫자,제곱,옵션 리스트로 분리
2.리스트순회하며 문제 조건에 맞게 시행
코드
public static int solution(String dartResult) {
int answer = 0;
List<String[]> arr = new ArrayList<>();
int nc = 0;
for (int i = 0; i < dartResult.length(); i++) {
char c = dartResult.charAt(i);
String key;
if (Character.isDigit(c)) {
if (i + 1 < dartResult.length()
&& Character.isDigit(dartResult.charAt(i + 1))) {
key = "" + c + dartResult.charAt(i + 1);
i++;
} else {
key = String.valueOf(c);
}
arr.add(new String[] { key, "num" });
nc++;
} else if (c == 'S' || c == 'D' || c == 'T') {
arr.add(new String[] { String.valueOf(c), "act" });
} else {
arr.add(new String[] { String.valueOf(c), "option" });
}
}
System.out.println(
arr.stream()
.map(Arrays::toString)
.toList());
int nowN = 0;
int[] nums = new int[nc];
int index = 0;
for (String[] item : arr) {
String key = item[0];
String value = item[1];
if (value.equals("num")) {
nowN = Integer.parseInt(key);
} else if (value.equals("act")) {
switch (key) {
case "S":
nowN = (int) Math.pow(nowN, 1);
break;
case "D":
nowN = (int) Math.pow(nowN, 2);
break;
case "T":
nowN = (int) Math.pow(nowN, 3);
break;
}
nums[index] = nowN;
index += 1;
} else {
switch (key) {
case "*":
nums[index - 1] *= 2;
if (index - 2 >= 0) {
nums[index - 2] *= 2;
}
break;
case "#":
nums[index - 1] *= -1;
break;
}
}
System.out.println("key: " + key + " / value: " + value);
}
System.out.println(Arrays.toString(nums));
answer = Arrays.stream(nums).sum();
System.out.println(answer);
return answer;
}
결과

gpt피드백
1. 알고리즘 평가
논리적으로 정확해.
특히 잘 처리한 부분은 10을 한 숫자로 묶은 것과 *에서 현재 점수뿐 아니라 직전 점수까지 수정한 부분이야.
알고리즘 개선점
가장 큰 개선점은 굳이 파싱 결과를 전부 저장했다가 다시 읽을 필요가 없다는 것이야.
2. 코드 평가
평가
현재 코드의 장점은 단계가 눈에 잘 보인다는 것이야.
개선점 1 — List<String[]> arr 제거
가장 큰 부분.
List<String[]> arr = new ArrayList<>();
문자열을 이미 한 번 읽었는데 정보를 저장하고 다시:
for (String[] item : arr)
로 읽고 있어.
한 번의 반복문에서 처리 가능해.
개선점 2 — nc 필요 없음
다트 게임은 항상 3번의 기회가 주어지니까:
int nc = 0;
...
nc++;
...
int[] nums = new int[nc];
까지 할 필요 없이:
int[] nums = new int[3];
이면 돼.
개선점 3 — Math.pow() 불필요
현재:
nowN = (int) Math.pow(nowN, 2);
Math.pow()는 double을 반환해서 다시 (int) 캐스팅하고 있어.
이 문제는 지수가 1, 2, 3밖에 없으니까:
case 'S':
break;
case 'D':
nowN *= nowN;
break;
case 'T':
nowN = nowN * nowN * nowN;
break;
로 충분해.
개선점 4 — "num", "act", "option" 문자열 비교 제거
현재:
if (value.equals("num"))
else if (value.equals("act"))
else
이건 네가 중간 파싱 자료구조를 만들었기 때문에 필요한 코드야.
직접 char를 판별하면 필요 없어져.
Character.isDigit(c)
c == 'S' || c == 'D' || c == 'T'
c == '*' || c == '#'
후기
옵션많아서 귀찮은 문제였다
'코테 > lvl1' 카테고리의 다른 글
| 프로그래머스 신규 아이디 추천(lvl1) 풀어보기 (0) | 2026.10.06 |
|---|---|
| 프로그래머스 성격 유형 검사하기(lvl1) 풀어보기 (0) | 2026.10.06 |
| 프로그래머스 예산(lvl1) 풀어보기 (0) | 2026.10.05 |
| 프로그래머스 연습문제(lvl1) 풀어보기 (0) | 2026.09.08 |
| 프로그래머스 명예의 전당(1)(lvl1) 풀어보기 (0) | 2026.09.08 |