230419_Algorithm

majungha·2023년 4월 19일
1

알고리즘

목록 보기
29/71

오늘의 알고리즘 👍

📝 1. [1차] 다트 게임


  • 카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다.
  • 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
  • 갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
  1. 다트 게임은 총 3번의 기회로 구성된다.
  2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
  3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
  4. 옵션으로 스타상() , 아차상(#)이 존재하며 스타상() 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
  5. 스타상()은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상()의 점수만 2배가 된다. (예제 4번 참고)
  6. 스타상()의 효과는 다른 스타상()의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)
  7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
  8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
  9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.
  • 0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

▷ 입출력 예

solution('1S2D*3T') // 37
solution('1D2S#10S') // 9
solution('1D2S0T') // 3
solution('1S*2T*3S') // 23
solution('1D#2S*3S') // 5
solution('1D#2S*3S') // -4
solution('1D2S3T*') // 59

▷ 내 풀이

▷ 해결 못함 ❌

  • 과제를 하느라 알고리즘을 풀지 못했다.

▷ 수업 풀이

const isBonus = ['S', 'D', 'T']; // 보너스를 체크할 수 있는 배열

function solution(dartResult) {
  // 1번째 게임부터 3번째 게임의 결과를 저장
  const answer = [];

  let score = ''; // 점수만 뽑아서 저장
  for (let i = 0; i < dartResult.length; i++) {
    if (Number.isNaN(Number(dartResult[i])) === false) {
      // 숫자 타입으로 변환했을 때 NaN 값이 아닌 경우 (= 숫자가 맞는 경우)
      score += dartResult[i];
    } else {
      // 숫자 타입으로 변환했을 때 NaN 값이 맞는 경우 (= 숫자가 아닌 경우)
      // 숫자가 아니다 = 보너스 또는 옵션
      if (isBonus.includes(dartResult[i])) {
        // 보너스 처리 (S, D, T)
        score = Number(score);

        if (dartResult[i] === 'D') {
          // 더블인 경우, 해당 점수에 2제곱
          score = score ** 2; // = Math.pow(score, 2);
        } else if (dartResult[i] === 'T') {
          // 트리플인 경우, 해당 점수에 3제곱
          score = score ** 3; // = Math.pow(score, 3)
        }
        console.log(score);
        answer.push(score);
        score = ''; // 다음 게임의 점수를 받아오기 위해 점수 초기화
      } else {
        // 옵션 처리 (*, #)
        if (dartResult[i] === '#') {
          // 아차상인 경우, 현재 게임의 점수를 - 한다
          answer[answer.length - 1] *= -1;
        } else {
          // 스타상인 경우, 현재 게임의 점수에 2를 곱한다
          answer[answer.length - 1] *= 2;

          // 현재 게임이 2번째 게임부터인지를 체크
          if (answer.length > 1) {
            // 이전 게임의 점수를 2배로 만든다.
            answer[answer.length - 2] *= 2;
          }
        }
      }
    }
  }
  return answer.reduce((acc, cur) => acc + cur);
}

▷ reduce 매서드 사용 풀이

const isBonus = ['S', 'D', 'T']; // 보너스를 체크할 수 있는 배열

function solution(dartResult) {
  let score = ''; // 점수만 뽑아서 저장
  let currentScore = 0; // 현재 게임의 연산된 점수를 저장
  let end = false; // 현재 게임이 종료되는 시점을 계산 = 점수를 최종 저장하는 시점

  return dartResult
    .split('')
    .reduce((acc, cur, i) => {
      if (!Number.isNaN(Number(cur))) {
        // 점수만 뽑아온다.
        score += cur;
        end = false; // 새 게임이 시작됐다.
      } else if (isBonus.includes(cur)) {
        // 보너스가 맞는 경우(S, D, T)
        score = Number(score);
        const squared = isBonus.indexOf(cur) + 1;

        currentScore = score ** squared;
        score = ''; // 점수 초기화

        // 현재 게임이 끝났는지
        if (
          !Number.isNaN(Number(dartResult[i + 1])) ||
          // 보너스 뒤에 있는 문자열이 숫자가 맞다면 (= 다음 게임의 점수라면)
          !dartResult[i + 1]
        ) {
          end = true; // 현재 게임은 보너스까지만 있다.
        }
      } else {
        // 옵션 처리 (*, #)
        end = true;
        if (cur === '#') {
          // 아차상인 경우, -1을 곱한다.
          currentScore *= -1;
        } else {
          // 스타상인 경우, 2를 곱한다.
          currentScore *= 2;

          if (acc.length > 0) {
            // 두번째 게임부터인 경우를 체크
            acc[acc.length - 1] *= 2;
          }
        }
      }
      if (end) {
        // 현재 게임이 완전히 종료되었을 때
        acc.push(currentScore); // 점수를 최종적으로 저장
      }
      return acc;
    }, [])
    .reduce((acc, cur) => acc + cur);
}

출처: 프로그래머스
출처: 코드캠프

profile
개발자 블로그 / 항상 겸손한 자세로 배우면서 성장하자 할 수 있다!

0개의 댓글