출처: 프로그래머스 코딩테스트 기업기출문제 다트 게임
(https://programmers.co.kr/learn/courses/30/lessons/17682)
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.
init. BONUS, OPTION 객체 선언
1. 각각 점수/보너스/옵션으로 이루어진 dartResult를 parse 함수를 이용해 분리한 후 results에 할당한다.
2. results에는 다트 결과들이 담겨 있고 그 결과안에는 점수가 포함되어 있다.
3. 만약 하나의 result가 *을 포함하고 있다면 그 앞의 result의 값은 2배가 된다.(허나 해당 result가 첫 인덱스에 있는 값이라면 X)
4. results의 모든 점수들을 더해서 반환한다.
const BONUS = {
S: 1,
D: 2,
T: 3,
}
const OPTION = {
"*": 2,
"#": -1,
undefined: 1,
}
function solution(dartResult) {
const results = parse(dartResult)
for (let i = 0; i < results.length; i++) {
if (results[i].option === "*") {
if (i > 0) {
results[i - 1].totalScore *= 2
}
}
}
return results.reduce((acc, cur) => acc + cur.totalScore, 0)
}
function parse(dartResult) {
let startIdx = 0
let endIdx = -1
const results = []
for (let i = 1; i < dartResult.length; i++) {
if (isNaN(+dartResult[i]) || isTen(dartResult, i)) {
continue
}
endIdx = i
results.push(new Result(dartResult.substring(startIdx, endIdx)))
startIdx = i
}
results.push(new Result(dartResult.substring(startIdx, dartResult.length)))
return results
}
function isTen(dartResult, i) {
if (dartResult[i] != 0) {
return false
}
if (dartResult[i - 1] != 1) {
return false
}
return true
}
class Result {
constructor(string) {
let i = 0
while (!isNaN(string[i++])) {}
this.score = +string.substring(0, i - 1)
this.bonus = string.charAt(i - 1)
this.option = string.charAt(i) || "undefined"
this.totalScore = Math.pow(this.score, BONUS[this.bonus]) * OPTION[this.option]
}
}
뭔가 이것저것 문자열도 자르고 계산도 해야되서 소스코드가 굉장히 길어졌는데 다른 사람들의 풀이를 보니 되게 간결하고 쉽게 풀이를 해놔서 보고 참고해야겠다는 생각이 들었다.