[Algorithm] [중복순열] 가위 바위 보

윤후·2022년 3월 3일
0

Section 3

목록 보기
12/41

문제

가위바위보 게임은 2인 이상의 사람이 동시에 '가위, 바위, 보'를 외치고 동시에 가위, 바위 또는 보 중에서 한 가지를 의미하는 손 모양을 내밀어 승부를 결정짓는 게임입니다. 세 판의 가위바위보 게임을 할 경우, 한 사람은 세 번의 선택(예. 가위, 가위, 보)을 할 수 있습니다. 세 번의 선택으로 가능한 모든 경우의 수를 구하는 함수를 작성합니다.

입력

없음

출력

  • 2차원 배열(arr[i])을 리턴해야 합니다.
  • arr[i]는 전체 경우의 수 중 한 가지 경우(총 세 번의 선택)를 의미하는 배열입니다.
  • arr[i]는 'rock', 'paper', 'scissors' 중 한 가지 이상을 요소로 갖는 배열입니다.
  • arr[i].length는 3

주의사항

  • 최종적으로 리턴되는 배열의 순서는 가중치 적용 정렬(Weighted Sort)을 따릅니다.
  • 중요도는 'rock', 'paper', 'scissors' 순으로 높습니다.
  • 쉽게 생각해 올림픽 순위 결정 방식을 참고하면 됩니다.
  • 금메달('rock')이 은메달('paper')보다 우선하고, 은메달('paper')이 동메달('scissors')보다 우선합니다.

입출력 예시

let output = rockPaperScissors();

console.log(output);
/*
    [
      ["rock", "rock", "rock"],
      ["rock", "rock", "paper"],
      ["rock", "rock", "scissors"],
      ["rock", "paper", "rock"],
      // ...etc ...
    ]
  */

Advanced

가위바위보 게임의 수를 나타내는 양의 정수 rounds가 주어질 경우, 해당 rounds 동안 선택할 수 있는 모든 경우의 수를 리턴하도록 함수를 작성해 보세요.

let output = rockPaperScissors(5);

console.log(output);
/*
    [
      ["rock", "rock", "rock", "rock", "rock"],
      ["rock", "rock", , "rock", "rock", "paper"],
      ["rock", "rock", , "rock", "rock", "scissors"],
      ["rock", "rock", "rock", "paper", "rock"],
      ["rock", "rock", "rock", "paper", "paper"],
      ["rock", "rock", "rock", "paper", "scissors"],
      ["rock", "rock", "rock", "scissors", "rock"],
      // ...etc ...
    ]
  */

코드

function rockPaperScissors (num) {
  // 3명이서 가위 바위 보를 한다.
  // TODO 가위 바위 보를 할 때 나올 수 있는 경우의 수를 모두 구하기.
  // 기본은 3명이서 하지만 매개변수인 num이 들어오게 된다면 num가지 자리 수의 경우의 수를 구하기.


  num = num || 3
  // 이게 있어야지 테스트 케이스가 돌아가게 된다.
  // num은 원래 매개변수로 없었지만, advanced를 실행하면서 나오게 된 매개변수이다.
  // 중복순열의 문제로는 3중 for문으로 배열속의 배열이 3개의 인덱스를 가졌다.
  // 두개의 변수의 값을 갖기 위해, num을 두가지의 사항으로 구분할 수 있도록 써준다.
  // num이 입력이 되지 않았을 경우 3을 넣어 실행할 수 있게 하며, 3이 아닌 다른 값으로 num이 된다면 그 값을 num자체로써 수행 될 수 있도록 한다. 
  
  let result = []
  // 빈 배열에 여러 경우의 수를 배열로 만들고 push하여 2차원 배열로 만들것임.
  
  let rps = ["rock","paper","scissors"] 
  // rps를 인덱스의 값으로 순회하면서 넣을 계획임.

  // num이 4이상 넘어가버리면 for문을 4중으로 쓰기는 힘드니까 재귀로 함수를 돌려주어야해.
  // 함수를 어떻게 만들까?
  // num만큼 재귀함수를 실행시킬 수 있는 count가 들어가야해. 그 count가 하나씩 줄어들면서 0이 되었을 때, 우리가 원하는 count 숫자만틈의 인덱스값을 얻을 수 있어.

  function jeaKwi (count, arr){
  
    if(count === 0){
    // 재귀를 끝낼 수 있는 조건이 무엇이 있을까
    // count가 0이 될 때 재귀가 끝내면 되지 않을까
    // 계속해서 -1이 되어 줘야 count가 0이 되겠지.

      result.push(arr)
      // 전역변수에 arr의 배열을 넣어주면서 재귀를 한번 빠져나가게 됨. 
      return;
    }

    else{
    // count가 0이 아닐경우에 실행.

      for(let i = 0 ; i < rps.length; i++){
      // for문안에 재귀를 실행해야 값이 바뀌면서 추가될테니까. for에 넣어줌.

        let arr1 = arr.concat(rps[i])
        // [...arr,rps[i]]와 같이 구조 분해할당으로 넣어 줄 수도 있음.

        jeaKwi(count-1, arr1)
        // 재귀함수를 불러오면서 count를 -1씩하고, 위의 concat의 결과를 불러온다.

        // count가 5일 경우,
        // jeaKwi(4,[...arr, rps[i]]) -> arr의 상태 ["rock"]                              조건 else를 통해 arr에 for문의 rps[0]번째 값인 rock이 들어가게 됨.
        // jeaKwi(3,[...arr, rps[i]]) -> arr의 상태 ["rock","rock"]                       조건 else를 통해 arr에 for문의 rps[0]번째 값인 rock이 들어가게 됨.
        // jeaKwi(2,[...arr, rps[i]]) -> arr의 상태 ["rock","rock","rock"]                조건 else를 통해 arr에 for문의 rps[0]번째 값인 rock이 들어가게 됨.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock","rock"]          조건 else를 통해 arr에 for문의 rps[0]번째 값인 rock이 들어가게 됨.

        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock","rock"]          result에 arr 값이 저장되게 된다. 재귀 한번 끝나서 count가 1로 돌아옴.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock","paper"]         for문으로 인해 i값이 1이 증가하게 되면서 rps[1]값인 paper가 들어가게 됨.
        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock","paper"]         result에 arr 값이 저장되게 된다. 재귀한번 끝나서 count가 1로 돌아옴.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock","scissors"]      for문으로 인해 i값이 1증가하게 되면서 rps[2]값인 scissors가 들어가게 됨.
        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock","scissors"]      result에 arr값이 저장되게 된다 재귀한번 끝나서 count가 2로 돌아옴.

        // jeaKwi(2,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock"]                 count가 2로 돌아옴에 따라 rock이 3개가 들어온 것으로 바뀌게 되고,
        // jeaKwi(2,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","paper"]                count가 2일 때의 for문의 i값이 1로 바뀌게 되면서 paper로 바뀌게 됨.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","paper","rock"]         조건 else를 통해 arr에 for문의 rps[0]번째 값인 rock이 들어가게 됨.
        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","paper","rock"]         result에 arr 값이 저장되게 된다. 재귀한번 끝나서 count가 1로 돌아옴.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","paper","paper"]        for문으로 인해 i값이 1증가하게 되면서 rps[1]값인 paper가 들어가게 됨.
        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","paper","paper"]        resuslt에 arr 값이 저장되게 된다 재귀한번 끝나서 count가 1로 돌아옴.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","paper","scissors"]     for문으로 인해 i값이 1증가하게 되면서 rps[2]값인 scissor가 들어가게 됨.
        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","paper","scissors"]     result에 arr 값이 저장되게 된다. 재귀한번 끝나서 count가 2로 돌아옴.

        // jeaKwi(2,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","rock"]                 count가 2로 돌아옴에 따라 rock이 3개가 들어온 것으로 바뀌게 되고,
        // jeaKwi(2,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","scissors"]             count가 2일 때의 for문의 i값이 2로 바뀌게 되면서 scissors로 바뀌게 됨.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","scissors","rock"]      조건 else를 통해 arr에 for문의 rps[0]번째 값인 rock이 들어가게 됨.
        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","scissors","rock"]      result에 arr 값이 저장되게 된다. 재귀한번 끝나서 count가 1로 돌아옴.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","scissors","paper"]     for문으로 인해 i값이 1증가하게 되면서 rps[1]값인 paper가 들어가게 됨.
        // jeaKwi(0,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","scissors","paper"]     resuslt에 arr 값이 저장되게 된다 재귀한번 끝나서 count가 1로 돌아옴.
        // jeaKwi(1,[...arr, rps[i]]) -> arr의 상태 ["rock""rock","scissors","scissors"]  for문으로 인해 i값이 1증가하게 되면서 rps[2]값인 scissors가 들어가게 됨.
        
        // 반복.
      }
    }

  }


  jeaKwi(num, [])
  // 재귀의 함수의 초깃값을 넣어준다.
  // num의 값을 전달해주고, arr의 초깃값을 빈 배열로 넣어주어 rps의 인덱스 값이 배열로써 들어갈 수 있게 해준다.

  return result;
  // 전역변수로 선언되어있는 result를 재귀를 돌며 값을 저장해두었으므로, result를 return해줌.
};

profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.

0개의 댓글

관련 채용 정보