[프로그래머스] Level 1 - 다트게임

SeungMin·2022년 8월 9일
0

Algorithm

목록 보기
2/3

문제 조건


입출력 예제


문제 풀이

function solution(dartResult) {
   
   // 받은 문자열을 배열로 변환
   let arr = dartResult.split('');
   
   // 배열을 순회하며 현재 인덱스의 원소가 1이고 다음 인덱스의 원소가 0이면
   // 둘을 합쳐서 10으로 만든다.
   for(let i = 0; i < arr.length-1; i++){
       if(arr[i] == "1" && arr[i+1] == '0') {
           arr[i] = "10";
           arr.splice(i+1,1);
       }
   }
   
   // 점수에 해당하는 값만 따로 저장할 배열 선언
   let hitArr = [];
   
   // 이중배열의 형태를 띄며 큰 배열 하나당 한번의 점수를 의미하며
   // 큰 배열에는 점수, 곱하기 >, 상유무가 있다.
   let onceArr = [];
   
   // 마지막에 점수를 담아서 반환할 변수 선언
   let answer = 0;
   
   
   // 전체 배열을 순회하며 점수부분을 검출
   arr.forEach((el,i)=>{
       if(el >= 0 && el <= 10)    
           
           // hitArr 배열의 목적은 다트를 던진 세번을 구분하기 위함
           hitArr.push(i);
   })
   
   // 첫번째 숫자는 3번을 나눌때 필요없으므로 shift
   hitArr.shift();
   
   
   // 3번의 다트 던지기를 구분해서 이중배열로 만든다.
   onceArr.push(arr.slice(0,hitArr[0]));
   onceArr.push(arr.slice(hitArr[0],hitArr[1]));
   onceArr.push(arr.slice(hitArr[1]))
   
   // 던지기별 점수를 저장할 배열 선언
   let instanceArr = [];
   
   // instanceArr에 push할 때 사용할 변수
   let instance = 0;
   
   
   // 위에서 만든 구분된 배열의 큰 배열(한번 던졌을 때 얻은 값들) 을 기준으로 forEach
   onceArr.forEach((el,i)=>{
       
       // 작은 배열(점수,배율,상유무) 을 기준으로 forEach
       onceArr[i].forEach((iel,ii)=>{
           
           // instance에 맞춘 점수를 대입
           if(ii === 0) instance = iel;
           
           // 배율을 계산
           if(ii === 1) {
               
               // 배율에 따라서 instance를 연산
               if(iel == 'S') instance = Math.pow(instance, 1);
               if(iel == 'D') instance = Math.pow(instance, 2);
               if(iel == 'T') instance = Math.pow(instance, 3);
           } 
           
           // 상유무를 판단
           if(ii === 2) {
               
               // 스타상일 경우
               if(iel == '*') {
                   
                   // 현재 다트던지기 판별식이 2번째 던지기 이상을 판별중일 경우
                   // 이전에 push한 회차의 점수를 2배로 만듦 (스타상)
                   if(i >= 1) instanceArr[i-1] = instanceArr[i-1] * 2;
                   
                   // 현재 판별중인 다트던지기 점수를 2배로 만듦
                   instance = instance * 2;
               }
               
               // 아차상일 경우 현재 판별중인 다트던지기 점수에 -1을 곱해줌
               if(iel == '#') instance = instance * -1;                   
           }
       })
       
       // 위의 식을 통해서 만들어진 다트던지기 점수를 instanceArr에 push
       instanceArr.push(instance);
       
       // 다음번 던지기 계산을 위해서 instance는 초기화
       instance = 0;
   })
   
   // 3번의 다트던지기를 모두 계산한 값을 가진 instanceArr을
   // forEach를 통해서 원소의 값을 모두 answer에 더해줌
   instanceArr.forEach((el,i)=>{
       answer += el;
   })
   
   // 얻어진 결과값을 리턴
   return answer;
}

마치며..
이번 문제를 풀면서 특히 forEach 문을 많이 사용한 것 같다.

평범하게 for 문을 사용하면 초기조건 제한조건 증감문
세가지 조건을 전부 작성하고 비교하려는 배열에서 어떤 문자를 찾는다면
for 문 안에 if 문까지 , if 문 안에 상세 조건까지 작성해야한다.

이번 문제의 경우는 forEach 를 이용해서 훨씬 수고를 덜었던 케이스다.

다트는 무조건 3번 던지며, 한번의 다트 던지기에서 딸려오는 정보또한
점수,배율,상유무 세가지로 매우 제한적이었기 때문에 forEach 문을 사용하는데
부담이 적었다.

앞으로도 문제의 제한조건을 잘 파악하고 어울리는 풀이법을 찾아야겠다.

profile
공부기록

0개의 댓글