본문 바로가기

Algorithm & World Class

[알고리즘] 05_[중복순열] 가위바위보

rockPaperScissors

문제

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

입력

  • 없음

출력

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

주의사항

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

입출력 예시

Advanced

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

 

mine

function rockPaperScissors (round) {
  const collection = ['rock', 'paper', 'scissors'];
  let result = [];
  
  if(round === undefined) round = 3;
  if(round <= 1) return collection.map((e) => [e]); //마지막 라운드에 들어갈 수 있는 
  // 모든 경우의 수가 배열로 생성된다.
  
  collection.forEach((e) => { //collection을 순회하며 fixer를 뽑아준다.
    const fixer = e;
    const permutationArr = rockPaperScissors(round - 1); //재귀로 한번 실행한다.
    const combineFixer = permutationArr.map((e) => [fixer, ...e]);
    result.push(...combineFixer);
  })

  return result;
};

 

reference

// Advanced가 포함된 레퍼런스 코드입니다.
const rockPaperScissors = function (rounds) {
  rounds = rounds || 3;
  const rps = ['rock', 'paper', 'scissors'];

  // 결과를 담을 배열 선언
  const outcomes = [];
  let permutate = function (roundsToGo, playedSoFar) {

    // rounds가 0일 경우 outcomes 배열에 삽입하고, 재귀에서 빠져나옵니다.
    if (roundsToGo === 0) {
      outcomes.push(playedSoFar);
      return;
    }

    // rps 배열을 한 번씩 순회합니다.
    for (let i = 0; i < rps.length; i++) {
      let currentPlay = rps[i];
      permutate(roundsToGo - 1, playedSoFar.concat(currentPlay));
    }
  };

  // 함수를 실행합니다.
  permutate(rounds, []);

  // outcomes를 반환합니다.
  return outcomes;
};

      /**
       * 이 재귀의 로직은 이렇습니다. 
       * 처음 실행된 반복문은 rps를 전부 순회해야 끝이 납니다.
       * 그러나 한 번 반복할 때마다 permutate 함수가 실행되고, 
       * rounds의 숫자는 짧아지며, playedSoFar에 요소가 계속 쌓일 것입니다.
       * 결국, roundsToGo가 0이 될 때까지 이 반복문은 rps[i]가 0일 것이며, 
       * playedSoFar에는 [rock, rock, rock]이 되어 outcomes에 Push하고, 종료하게 됩니다.
       * return이 되었으니, 한 번의 재귀 호출이 끝났습니다. 마지막 호출 바로 전으로 돌아가,
       * for문은 i = 1을 가리키게 될 것이고, [rock, rock, paper]을 삽입한 뒤 호출을 하게 됩니다.
       * roundsToGo가 0이 되어, 해당 배열은 outcomes 배열에 삽입됩니다.
       * 이런 식으로 모든 호출의 반복문이 끝날 때까지 반복하며 outcomes에 경우의 수 요소들이 담기게 됩니다.
       */