Bleeding edge

[프로그래머스] [1차] 다트 게임 - 자바스크립트 본문

코딩테스트 공부

[프로그래머스] [1차] 다트 게임 - 자바스크립트

codevil 2022. 4. 28. 21:27

https://programmers.co.kr/learn/courses/30/lessons/17682

 

코딩테스트 연습 - [1차] 다트 게임

 

programmers.co.kr

문제를 두번 다 풀었는데, 좀 아쉬운게 있어서, 다른사람의 풀이도 봤었다

우선 아래에 있는 것은 내풀이이다

function solution(d) {
    let list = [];
    for(let i = 0 ; i<d.length;i++){
        let num = 1
        if(d[i]==="1"&&d[i+1]==="0"){
            num= num*10;
            i++
        }else{
            num = num*d[i]
        }
            i++;
        //부호 시작
        if(d[i]==="D"){
            num = num**2
        }else if(d[i]==="T"){
            num = num**3
        }
            //특수기호 체크
        if(d[i+1]==="*"){
            num = num*2
            list[list.length-1] = list[list.length-1]*2
            i++;
        }else if(d[i+1] ==="#"){
            num = num*(-1)
            i++
        }

        list.push(num)

    }
    return list.reduce((a,b)=>a+b,0)
}

우선, 아쉬웠던건, 각 케이스(3번의 발사)를 정규식을 통해서 분리를 해야했는데, 이게 어떻게 해야할지 감이 너무 안잡혀서, for문을 억지로 만든 케이스다. (이전에 풀었던것도 전혀 다르지 않았다)

다른사람의 풀이를 보던중에, 정규식을 정말 예쁘게 푸신분이있는데 (이분은 정말 코드를 예쁘게 쓰시는거 같아서 배우고싶다

출처 !! https://github.com/codeisneverodd/programmers-coding-test

 

GitHub - codeisneverodd/programmers-coding-test: ⭐️ 프로그래머스 코딩테스트를 통과한 JavaScript 해답을 찾

⭐️ 프로그래머스 코딩테스트를 통과한 JavaScript 해답을 찾아보세요! Contribute to codeisneverodd/programmers-coding-test development by creating an account on GitHub.

github.com

 

이분의 정규식은 다음과 같았다

/\d{1,2}[SDT]{1}[*|#]?/g

여기서 / /g는 i를 쓸게아니면 공통사항이니까 제외하겠습니다.

\d : d는 여기서 digit을 말하는데 숫자를 이야기합니다. 처음에 숫자를 받겠다는 의미이지요. 그뒤에 있는 {1, 2}는 다음과 같습니다, 1개에서 2개까지의 숫자를 받겠다! 라는 의미입니다 요기 문제에서는 0에서 10까지의 숫자를 받기때문에 1,2로 설정한 것입니다. 

[SDT]는 SDT 세가지 케이스를 정한경우입니다. 여기서 주의 해야할 것은 [ ] 안에 있는 것들은 한글자씩, 취급을 하며, ( ) 안에 있는 케이스들은 한번에 묶어서 분류합니다 즉 [SDT]는 ["S", "D", "T"] 와 같이 Array 안에서 각각의 분류들을 따진다 라고 생각하면 쉽습니다(이런 개념은아닌데, 정규식 안에서 너무나 괄호가 많기에, 연상법을 사용한다면 [] 괄호는 Array 괄호와 같기때문에 각각을 분류해서 본자! 라는 이야기였습니다) (SDT)는, 함수에 있는 괄호와 같은걸 봐서는 SDT를 한개로 본다! 라고생각하고 SDT자체를 한개로 연상하면 쉽습니다. 아무래도.. 글을 쓰다보니 괄호의 의미에 대해서 조금 더 공부해 보는 것도 좋을 것 같다고 생각이 듭니다....  그리고 뒤에 있는 {}은, 1개를 받겠다는 의미입니다.

[*|#]? 사실, 여기서 |는 안넣어도 됩니다(SDT와 같은 이유로)  마지막에 있는 ?같은 경우 의미는, {0, 1}과 같습니다. 즉, 앞에있는 *와 #가 1개가 있거나 없거나라는 뜻입니다.

 

 

사실 제가 만일 이 풀이를 했다면,

const regex = /\d{1,2}[SDT]{1}[*#]{0,1}/g;
list = list.map((v) => v.match(regex));

이렇게, list map으로, v.match를 시키고 했을꺼 같은데

  for (const dart of dartResult.match(regex)) {
  
  }

와 같이, 보기 좋게, for of로 접근을 하였다. 비슷한 케이스가 있으면 나도 반영하도록 해야겠다.

이분의 풀 풀이이다

//https://github.com/codeisneverodd/programmers-coding-test
//더 좋은 풀이가 존재할 수 있습니다.
//정답 1(🎩 refactor 220425) - codeisneverodd
function solution(dartResult) {
  const regex = /\d{1,2}[SDT]{1}[*|#]?/g;
  let result = [];
  for (const dart of dartResult.match(regex)) {
    const game = [...dart.split(/([SDT]{1})/)];
    const score = game[0];
    let bonus = 1;
    let option = 1;
    if (game[1] === "S") bonus = 1;
    if (game[1] === "D") bonus = 2;
    if (game[1] === "T") bonus = 3;

    if (game[2] === "*") {
      if (result.length !== 0) result[result.length - 1] *= 2;
      option = 2;
    }
    if (game[2] === "#") option = -1;

    result.push(score ** bonus * option);
  }

  return result.reduce((a, b) => a + b);
}