Algorithm/Java

프로그래머스 [1차] 다트 게임 java :: 2018 KAKAO BLIND RECRUITMENT

고고마코드 2022. 7. 1. 17:57
반응형
17682번

코딩테스트 연습 - [1차] 다트 게임 | 프로그래머스 (programmers.co.kr)

 

코딩테스트 연습 - [1차] 다트 게임

 

programmers.co.kr


풀이

사실 옵션만 잘 구분하면 되는 문제이기는 한데 주의할 점이 몇 개 있습니다.

✔ 숫자는 0~9 까지만 오는 게 아니라 10도 올 수 있다.

✔ 옵션 *, #은 있을 수도 있고 없을 수도 있다.

✔ 옵션 *은 현재 점수뿐만 아니라, 이전 점수까지 영향을 준다. 그래서 이전 점수가 있는지 없는지부터 체크해야 한다.

 

  • 풀이1
public int solution2(String dartResult) {
	Stack<Integer> stack = new Stack<Integer>();

	for (int i = 0; i < dartResult.length(); i++) {
		char dart = dartResult.charAt(i);
		if (Character.isDigit(dart)) {
			int dartInt = Character.getNumericValue(dart);
			if (dartInt == 1 && dartResult.charAt(i + 1) == '0') {
				dartInt = 10;
				i++;
			}
			stack.push(dartInt);
		} else {
			int prev = stack.pop();
			switch (dart) {
			case 'D':
				prev = prev * prev;
				break;
			case 'T':
				prev = prev * prev * prev;
				break;
			case '*':
				prev *= 2;
				if (!stack.isEmpty()) {
					stack.push(stack.pop() * 2);
				}
				break;
			case '#':
				prev *= -1;
				break;
			}
			stack.push(prev);
		}
	}

	int answer = 0;
	while (!stack.isEmpty())
		answer += stack.pop();

	return answer;
}

문제를 읽자마자 제일 먼저 생각난 게 스택으로 풀면 쉽게 풀 수 있을 것 같았어요.

점수만 스택에 넣고

보너스나 옵션은 스택에서 점수를 가져와서 계산한 다음 다시 스택에 넣어주는 식으로 풀었어요.

 

나머진 기본적인 연산이니 주의할 점만 설명할게요.

 

if(dartInt == 1 && dartResult.charAt(i+1) == '0')

숫자는 10도 올 수 있기 때문에 만약에 문자가 1이면 그 다음 문자까지 꼭 확인을 해야 해요.

처음에는 혹시 IndexOutOfBounds 에러 발생할까봐 length 체크까지 조건에 걸었었는데, 생각해보니 보너스는 무조건 오기 때문에 걸지 않아도 되더라구요.

아무튼, 문자가 "10"이 이렇게 붙어있으면 스택에는 10을 숫자 쌓아야 해요. 당연히 인덱스 하나 건너뛰었으니까 인덱스도 증가시켜줘야 하구요.

 

✅ 옵션 스타상(*)

스타상은 현재 점수만 x2 가 아니라 이전 점수도 x2 를 해줘야 해요.

근데 첫 번째 점수라서 이전 점수는 없을 수도 있잖아요? 그 부분을 꼭 체크해야 해요.

이전 점수 가져와서 다시 넣어주고, 그 다음 현재 점수 넣어야 해요! 

스타상은 다음 점수에도 나올 수 있기 때문에 반드시 점수 순서를 지켜서 스택에 넣어야 합니다!

 

✔ 테스트 케이스 처리 속도: 평균 0.16ms

 

  • 풀이2
public int solution(String dartResult) {
	int array[] = new int[3];
	int idx = -1, count = 0;

	for (int i = 0; i < dartResult.length(); i++) {
		char dart = dartResult.charAt(i);
		if (Character.isDigit(dart)) {
			int dartInt = Character.getNumericValue(dart);
			if (dartInt == 1 && dartResult.charAt(i + 1) == '0') {
				dartInt = 10;
				i++;
			}
			array[1 + (idx++)] = dartInt;
			count++;
		} else {
			int prev = array[idx];
			switch (dart) {
			case 'S':
				break;
			case 'D':
				prev = prev * prev;
				break;
			case 'T':
				prev = prev * prev * prev;
				break;
			case '*':
				prev *= 2;
				if (count > 1) {
					array[idx - 1] *= 2;
				}
				break;
			case '#':
				prev *= -1;
			}
			array[idx] = prev;
		}
	}

	int answer = 0;
	for (int score : array)
		answer += score;

	return answer;
}

스택 안 쓰고도 풀어보고 싶었어요.

이번에는 배열 버전이에요.

기본적으로 로직은 스택이랑 똑같이 풀었는데, 배열이라서 인덱스 관리에 조금 더 신경썼어요.

스타상 때문에 전체 점수의 개수를 구하는 count 라는 변수를 하나 추가했어요.

그거 빼고는 스택이랑 다 똑같아요.

 

테스트 케이스 처리속도: 0.05ms

 

역시 순정이라 그런지 처리속도는 배열이 3배 정도 빠르네요.

반응형