프로그래머스 2018 KAKAO BLIND RECRUITMENT Level 1 문제 다트 게임을 Java를 이용해 풀어보았다.
Level 1인데 왜케 귀찮아 짜증나게
문제 링크 첨부한다.
https://programmers.co.kr/learn/courses/30/lessons/17682
처음에는 숫자를 만나면 그 전까지 붙여온 문자열을 떼서 저장하고, 이 작업을 반복하다가 마지막에 남아있는 문자열까지 추가해주는 식으로 파싱을 할까 생각했다. 근데 최근 카카오 기출을 풀면서 정규표현식을 생각보다 많이 쓰는 것을 확인하고 그래도 정규표현식 함 써보까 해서 좀 찾아보며 풀었다.
결국 중요한 건 점수와 그 뒤의 영역 및 옵션을 구분해서 처리할 수 있도록 파싱해야 하는 것이다. 그림으로 보면 위와 같은 건데, 파싱을 하되 1D#
이렇게 통째로 끊어버리면 다시 점수만 분리해야 하는 귀찮은 상황이 벌어지기 때문에 아예 처음부터 숫자는 숫자대로, 문자는 문자대로 따로 분리한 후에 이 두 녀석을 함께 저장하는 식으로 파싱했다.
이를 위해서 Info
클래스를 정의했다.
static class Info{
int score; // 점수
String type; // 영역과 옵션 함께, 어차피 1글자 아님 2글자
Info(int score, String type){
this.score = score;
this.type = type;
}
}
그리고 정규표현식을 이용해서 숫자끼리, 문자끼리 따로 분리한 후에 Info
객체를 만들어주는 식으로 파싱을 수행했다.
static ArrayList<Info> list = new ArrayList<>();
String[] tmp1 = (dartResult.split("\\D+")); // 숫자만
String[] tmp2 = dartResult.split("[0-9]+"); // 문자만
for(int i=0; i<tmp1.length; i++){
int score = Integer.parseInt(tmp1[i]);
list.add(new Info(score, tmp2[i+1]));
}
근데 tmp2
의 결과를 보면 "", "D#", #S*", "S"
이런 식으로 맨 앞에 빈 문자열이 하나 발생하기 때문에 i+1
로 처리해주면 된다.
그럼 위의 list
를 순회하며 점수를 업뎃해주면 된다.
static ArrayList<Integer> score = new ArrayList<>(list.size());
static void getScore(){
for(int i=0; i<list.size(); i++){
Info cur = list.get(i);
int curScore = 0;
switch(cur.type.charAt(0)){ // 일단 default 점수 계산해주고
case 'S':
curScore += cur.score;
break;
case 'D':
curScore += (cur.score * cur.score);
break;
case 'T':
curScore += (cur.score * cur.score * cur.score);
break;
}
if(cur.type.length()==2){ // 옵션도 붙었을 때
if(cur.type.charAt(1)=='*') { // 스타상
curScore *= 2;
if(i>0) score.set(i-1, score.get(i-1)*2);
}
else curScore *= -1; // 아차상
}
score.add(i, curScore); // score 배열에 넣어주자
}
}
이렇게 하면 각 부분에 맞는 점수들이 score
리스트 안에 쭉 계산이 완성됐다.
이제 다 더해서 반환해주면 된다.
getScore();
for(int s: score) answer += s;
return answer;
아래는 내가 제출한 전체 코드다.
import java.util.ArrayList;
public class DartGame {
static ArrayList<Info> list = new ArrayList<>();
static ArrayList<Integer> score = new ArrayList<>(list.size());
static int solution(String dartResult) {
int answer = 0;
String[] tmp1 = (dartResult.split("\\D+"));
String[] tmp2 = dartResult.split("[0-9]+");
for(int i=0; i<tmp1.length; i++){
int score = Integer.parseInt(tmp1[i]);
list.add(new Info(score, tmp2[i+1]));
}
getScore();
for(int s: score) answer += s;
return answer;
}
static void getScore(){
for(int i=0; i<list.size(); i++){
Info cur = list.get(i);
int curScore = 0;
switch(cur.type.charAt(0)){
case 'S':
curScore += cur.score;
break;
case 'D':
curScore += (cur.score * cur.score);
break;
case 'T':
curScore += (cur.score * cur.score * cur.score);
break;
}
if(cur.type.length()==2){ // 옵션도 붙었을 때
if(cur.type.charAt(1)=='*') {
curScore *= 2;
if(i>0) score.set(i-1, score.get(i-1)*2);
}
else curScore *= -1;
}
score.add(i, curScore);
}
}
static class Info{
int score;
String type;
Info(int score, String type){
this.score = score;
this.type = type;
}
}
public static void main(String[] args) {
String dartResult = "1D#2S*3S";
int answer = solution(dartResult);
System.out.println(answer);
}
}
오늘 배운 것
정규표현식 계속 써보면서 익혀가자. 워낙 용법이 많은데 쓰는 건 거의 정해져있는 것 같다. 잘 기록해두면서 체화시켜보자.