Programmers.js - [1차] 다트 게임

박요셉·2024년 6월 22일
1

Programmers.Js

목록 보기
25/26
post-custom-banner

아이유 이쁘다..하면서 금방 풀고 다음 문제 풀어야지! 하고 시작했으나 2시간걸렸음 ㅋㅋ;;

최종 코드를 올리고 어떤 부분을 간과해서 오래 걸렸는지와 배운점을 적어보겠음.

최종 코드

const squareObj = { S: 1, D: 2, T: 3 };
const awardObj = { '#': -1, '*': 2 };

function solution(dartResult) {
    const dartResultArr = dartResult.match(/\d{1,2}[A-Z][#*]?/g);
    let scores = [];
 
    
    dartResultArr.forEach((result, idx) => {
        const [score, isGetAward] = getScore(scores, result, idx);
        scores.push(score);
       
    });

    const totalScore = calculateTotalScore(scores);
    
    return totalScore;
}

const getScore = (scores, result, idx) => {
    let score = 0;
    let isGetAward = { isIt: false, award: '' };
    let baseScore, bonus, option;
    if (result.length === 2) {
        baseScore = result[0];
        bonus = result[1];
        option = '';
    } else if (result.length === 3 && (result[2] === '*' || result[2] === '#')) {
        baseScore = result[0];
        bonus = result[1];
        option = result[2];
    } else {
        baseScore = result.slice(0, 2);
        bonus = result[2];
        option = result[3] || '';
    }

    score = Math.pow(Number(baseScore), squareObj[bonus]);
    
    if (option) {
        if (option === '*') {
            score *= 2;
            if (idx > 0) {
                scores[idx - 1] *= 2;
            }
        } else if (option === '#') {
            score *= -1;
        }
        isGetAward = { isIt: true, award: option };
    }

    return [score, isGetAward];
};

const calculateTotalScore = (scores) => {
    return scores.reduce((acc, score) => acc + score, 0);
};

1. 정규식

dartResult.match(/\d+[A-Z][#*]?/g);
기존 정규식 코드는 위와 같았음.
숫자 여러개 올 수 있습니다, 문자열 와요, #또는*옵니다 라는 뜻으로 적었음.

dartResult.match(/\d{1,2}[A-Z][#*]?/g);
와 같이 숫자 1자리, 2자리 숫자가 와요 라고 적을 수도 있음

2. 점수 분리 및 계산 오류

  • 문제 : 개별 점수 문자열에서 점수, 보너스, 옵션을 제대로 분리하지 못하였음.
  • 해결 : 점수, 보너스, 옵션을 정확히 분리하고, 각 부분을 적절히 처리하도록 수정 + 두 자리 숫자를 처리하는 경우를 추가하여 문제 해결
let baseScore, bonus, option;

if (result.length === 2) {
    baseScore = result[0];
    bonus = result[1];
    option = '';
} else if (result.length === 3 && (result[2] === '*' || result[2] === '#')) {
    baseScore = result[0];
    bonus = result[1];
    option = result[2];
} else {
    baseScore = result.slice(0, 2);
    bonus = result[2];
    option = result[3] || '';
}
  • 느낀점 => 기능에 대한 것을 생각할 때 어떤 조건들이 있는가 그 조건들을 이루는 상태들은 어떻게 이루어져 있는지 파악 후 먼저 분리하고 시작하는 것이 좋다고 느낌

3. 옵션 처리 오류

  • 문제 : * 옵션이 적용된 경우 현재 점수와 이전 점수를 두 배로 처리하는 로직을 누락시킴

  • 해결 : * 옵션이 있는 경우 현재 점수를 두 배로 만들고, 이전 점수가 있다면 이전 점수를 직접 접근하여 두배로 만드는 로직을 추가

if (option) {
    if (option === '*') {
        score *= 2;
        if (idx > 0) {
            scores[idx - 1] *= 2; <= 이전 값에 바로 할당시켜버림
        }
    } else if (option === '#') {
        score *= -1;
    }
    isGetAward = { isIt: true, award: option };
}

4. 결과 계산 누락

  • 문제 : 최종 점수를 계산하는 로직이 올바르지 못했음.
  • 해결 : 각 값들을 scores배열에 모은 후 해당 배열의 값들을 합산하는데에 reducer를 사용하여 계산 후 리턴
const calculateTotalScore = (scores) => {
    return scores.reduce((acc, score) => acc + score, 0);
};

원래 알고리즘 푸는데 30분정도 넘으면 답지를 봐버리는데 이게 될듯 안되고 될듯 안되면서 애태우는게 있어서 2시간동안 겨우 풀어냈음.. 함수를 찾거나 정규식 찾을 땐 검색을 하긴 했지만 답지를 보진 않았으니 그나마 만족스러운듯

profile
개발자 지망생
post-custom-banner

0개의 댓글