[프로그래머스 | Javascript] 2018 KAKAO BLIND RECRUITMENT - [1차] 다트 게임

박기영·2022년 9월 13일
0

프로그래머스

목록 보기
39/159

solution

function solution(dartResult) {
    // 하나의 계산이 완료되면 이 배열에 넣는다
    let comp = [];
    
    // 계산되기 전 숫자들은 여기에 넣는다
    let tmp = [];
    
    let dartArr = dartResult.split("");
    
    while(dartArr.length > 0){
        let shiftedItem = dartArr.shift();
        
        // shift 한 것이 S,D,T가 나오기 전에는 tmp 배열에 넣는다
        if(shiftedItem !== "S" && shiftedItem !== "D" && shiftedItem !== "T" && shiftedItem !== "*" && shiftedItem !== "#"){
            tmp.push(shiftedItem);
        } else {
            // 10은 1,0 이렇게 들어가 있으므로 join을 해준다.
            let num = Number(tmp.join(""));
            
            if(shiftedItem === "S"){
                comp.push(num ** 1);
            } else if(shiftedItem === "D"){
                comp.push(num ** 2);
            } else if(shiftedItem === "T"){
                comp.push(num ** 3);
            }
            
            // tmp 내부에 있는 숫자들은 계산이 완료되었으므로, 초기화
            tmp = [];
            
            let compLen = comp.length;
            
            // 옵션 계산            
            let noOption = 0;
            
            // shift가 완료된 dartResult 배열의 가장 앞은
            // 숫자일 수도, 옵션일 수도 있다.
            let isOption = dartArr[0];
            
            if(isOption === "*"){
                dartArr.shift();
                
                if(compLen > 1){
                    // comp 배열의 길이가 1보다 크면 이번 계산과 이전 계산 모두에 적용해야한다.
                    // 따라서, pop을 두 번하고
                    // 다시 넣어줄 때는 순서를 반대로 해야한다는 점에 주의!
                    let last = comp.pop();
                    let beforeLast = comp.pop();
                    
                    comp.push(beforeLast * 2);
                    comp.push(last * 2);
                } else {
                    let last = comp.pop();
                    
                    comp.push(last * 2);
                }
            } else if(isOption === "#"){
                dartArr.shift();

                let last = comp.pop();
                    
                comp.push(last * -1);
            }
        }
    }
    
    let sum = comp.reduce((acc, curr) => {
        return acc + curr;
    }, 0);
    
    return sum;
}

문제를 어떻게 풀어낼지 고민하는데 10분이 넘게 걸린 것 같다. 총 40분 가량 작성했다.
전부 작성하고 보니...코드가 너무 길다.
너무 세세하게 분기 처리를 한 것인가 싶기도 하고, 알고리즘 지식을 활용한 것 같지도 않다.
지금보니 tmp, comp 배열은 stack 구조를 사용하는 것과 같은 느낌이다.

카카오 공식 해설집에 따르면 문자열을 앞에서부터 잘라내어 사용하는 능력을 평가한 것이라고 한다.
그 점에서는 알맞게 진행한 것 같다.
추가적으로 10점의 경우를 예외적으로 판단해야 하는 것 또한 명시되어 있다.
이 점도 잘 해냈다.

다만..난이도 하 문제인데 너무 많은 시간을 사용했다는 것이 슬프다..

다른 분 풀이

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);
}

다른 분의 풀이를 가져와봤다. 정규식을 활용하신 것 같다.
처음부터 객체에 각 문자열의 의미를 정의해놓으셨다.
풀이에 대한 코멘트를 보면 잘 해결되지 않는 테이스 케이스도 있는 모양이다.

다만, 정규식을 활용했다는 점과, match() 메서드를 사용했다는 점이 인상적이다.
프로그래머스 문제를 풀다보니 정규식과 match() 메서드가 풀이에 꽤 자주 등장하는 느낌이다.

참고로, Math.pow()는 제곱을 계산해주는 메서드이다.
Math.pow(2,4) = 2**4 = 16
이런 느낌이다.

profile
나를 믿는 사람들을, 실망시키지 않도록

0개의 댓글