https://programmers.co.kr/learn/courses/30/lessons/17682
다트 게임의 기회 : 총 3회
점수|보너스|[옵션]으로 이루어진 문자열 3세트가 주어진다.
0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.
- 각 기회마다 얻을 수 있는 점수: 0점 ~ 10점
- 보너스
- S : 점수의 1제곱
- D : 점수의 2제곱
- T : 점수의 3제곱
- 옵션
- 옵션은 존재할 수도, 존재하지 않을 수도 있다.
- 스타상(*) : 해당 점수와 바로 전에 얻은 점수를 각각 2배로 만든다.
- 첫 번째 기회에서 스타상이 나올 경우 첫 번째 점수만 2배가 된다.
- 다른 스타상 효과와 중첩 가능(4배)
- 아차상(#) : 해당 점수는 마이너스된다.
- 스타상과 아차상이 중첩돌 경우 중첩된 아차상의 점수는 -2배가 된다.
1. 점수 vs 보너스/옵션으로 문자열 분리하기
2. 보너스/옵션 적용하여 점수 계산하기
3. 총 점수 return
(1) 처음 짠 코드
function solution(dartResult) {
let num = [];
for (let x of dartResult) {
if (!isNaN(x)) num.push(Number(x));
else if (x === 'D') {
num[num.length - 1] = Math.pow(num[num.length - 1], 2);
} else if (x === 'T') {
num[num.length - 1] = Math.pow(num[num.length - 1], 3);
} else if (x === '*') {
if (num.length !== 1) num[num.length - 2] *= 2;
num[num.length - 1] *= 2;
} else if (x === '#') {
num[num.length - 1] *= (-1);
}
console.log(num)
}
return num.reduce((acc, cur) => acc + cur, 0);
}
이렇게 풀면 숫자로 10이 들어올 경우를 해결해주지 못함.
(2) 다시 짠 코드
function solution(dartResult) {
let numArr = dartResult.split(/[^0-9]/).filter((v) => v !== "");
let strArr = dartResult.split(/[0-9]/).filter((v) => v !== "");
for (let i = 0; i < strArr.length; i++) {
for (let j = 0; j < strArr[i].length; j++) {
if (strArr[i][j] === 'D') {
numArr[i] = Math.pow(numArr[i], 2);
} else if (strArr[i][j] === 'T') {
numArr[i] = Math.pow(numArr[i], 3);
} else if (strArr[i][j] === '*') {
if (i !== 0) numArr[i - 1] *= 2;
numArr[i] *= 2;
} else if (strArr[i][j] === '#') {
numArr[i] *= (-1);
}
}
}
return numArr.reduce((acc, cur) => acc + Number(cur), 0);
}
문제를 풀다보니 느낀 점...
정규 표현식과 문자열 나누는 부분에 대해 취약하다는 것을 깨달았다.
매번 저 split함수는 쓸 때마다 사용법을 찾아보게 된다...😂
function solution(dartResult) {
const reg = /[\d]+[SDT][*#]*/g;
const input = dartResult.match(reg);
const result = [];
for (let i = 0; i < input.length; i++) {
let number = input[i].match(/[\d]+/g)[0];
const bonus = input[i].match(/[SDT]/g)[0];
const option = input[i].match(/[*#]/g);
switch (bonus) {
case 'S':
number = Number(number);
break;
case 'D':
number = Math.pow(number, 2);
break;
case 'T':
number = Math.pow(number, 3);
break;
}
result[i] = number;
if (option) {
switch (option[0]) {
case '*':
result[i - 1] *= 2;
result[i] *= 2;
break;
case '#':
result[i] *= -1;
break;
}
}
}
return result.reduce((acc, cur) => {
return acc + cur;
});
}