카카오톡에 뜬 네 번째 별! 심심할 땐? 카카오톡 게임별~
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
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 1S*2T*3S 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
t
로 바꾼 다음에 t
를 다시 "10"으로 바꾸도록 해서 해결했다.S
가 있으면 이전 값에 1승, D
가 있으면 이전 값의 2승, T
가 있으면 이전 값의 3승을 해준다.*
이 있으면 이전 두 값을 2배해서 갱신, #
이 있으면 이전 값의 -1배해서 갱신한다.function solution(dartResult) {
let answer = [];
let arr = dartResult.split(10).join('t').split('');
for(let i=0;i<arr.length;i++){
if(arr[i] === "t") arr[i] = "10";
if(arr[i] === "S") answer.push(arr[i-1]**1);
if(arr[i] === "D") answer.push(arr[i-1]**2);
if(arr[i] === "T") answer.push(arr[i-1]**3);
if(arr[i] === "*"){
answer[answer.length-1] *= 2;
answer[answer.length-2] *= 2;
}
if(arr[i] === "#") answer.push(answer.pop() * (-1));
}
return answer.reduce((acc,cur) => acc+cur);
}
시간은 평균적으로 0.08초에서 0.1초, 메모리는 33.4MB 정도를 차지했다.
object를 이용해 연산을 수행하는 문자들을 따로 담아놓고, 해당 문자로 split하여 계산을 수행한다.
정규표현식 이용.
\D
: 숫자가 아닌 문자 포함.
**
사용하는 대신 Math.pow()
를 사용해도 된다.
function solution(dartResult) {
const bonus = { 'S': 1, 'D': 2, 'T': 3 },
options = { '*': 2, '#': -1, undefined: 1 };
let darts = dartResult.match(/\d.?\D/g);
for (let i = 0; i < darts.length; i++) {
let split = darts[i].match(/(^\d{1,})(S|D|T)(\*|#)?/),
score = Math.pow(split[1], bonus[split[2]]) * options[split[3]];
if (split[3] === '*' && darts[i - 1]) darts[i - 1] *= options['*'];
darts[i] = score;
}
return darts.reduce((a, b) => a + b);
}
시간은 평균적으로 0.2초에서 0.3초, 메모리는 33.4MB 정도를 차지했다.
시간은 내가 푼 방식이 훨씬 빠르게 나왔지만, 10을 쪼개는 방식과 매치되는 것을 찾는 방식이 이게 더 깔끔하고 확장성도 있기 때문에 정규표현식을 사용하는게 좋은듯 하다.
정규표현식 자료