toy01.rockPaperScissors

Judo·2020년 12월 12일
0
post-thumbnail
post-custom-banner

문제


  • 가위바위보 게임은 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 ...
    ]
  */

작성 코드

const rockPaperScissors = function (rounds) {
 
  rounds = rounds || 3; //rounds가 존재하면 rounds 할당, 없다면 3 
  const rps = ['rock', 'paper', 'scissors']; 

  const outcomes = []; //closure
  
  
  /*
    재귀 호출할 함수 permutate	를 생성한다.
    주어진 rounds를 증감시키면서 0이 된 경우 가위바위보를 모두 진행했으므로 outcomes에 결과값을 push한다.
  */
  
  let permutate = function (rounds, playedSoFar) {
    if (rounds === 0) {
      outcomes.push(playedSoFar);
      return;
    }

    for (let i = 0; i < rps.length; i++) {
      let currentPlay = rps[i];
      permutate(rounds - 1, playedSoFar.concat(currentPlay));
    }
  };

  permutate(rounds, []);
  return outcomes;
  /*
  if rounds === 2라면 
  
  1. permutate(2, []) 호출
  2. currentPlay = ['rock'] => permutate(1, ['rock'])
    2.1 currentPlay = ['rock'] => permutate(0, ['rock', 'rock'])
    2.2 currentPlay = ['rock'] => permutate(0, ['rock', 'paper'])
    2.3 currentPlay = ['rock'] => permutate(0, ['rock', 'scissors'])
    2.4 2.1 ~ 2.3이 진행되는 동안 outcomes에는 가위바위보 결과가 push
  3. currentPlay = ['paper'] => permutate(1, ['paper'])
   	3.1 currentPlay = ['rock'] => permutate(0, ['paper', 'rock'])
    3.2 currentPlay = ['paper'] => permutate(0, ['paper', 'paper'])
    3.3 currentPlay = ['scissors'] => permutate(0, ['paper', 'scissors'])
    3.4 3.1 ~ 3.3이 진행되는 동안 outcomes에는 결과가 push 
  4. currentPlay = ['scissors'] => permutate(1, ['scissors'])
    4.1 currentPlay = ['rock'] => permutate(0, ['scissors', 'rock'])
    4.2 currentPlay = ['paper'] => permutate(0, ['scissors', 'paper'])
    4.3 currentPlay = ['scissors'] => permutate(0, ['scissors', 'scissors'])
    4.4 4.1 ~ 4.3이 진행되는 동안 outcomes에는 결과가 push 
  */


};

어려웠던 점


간단한 재귀 호출, 익숙한 재귀 호출은 이해하는데 무리가 없는데 문제가 조금 다르게 나오거나 복잡해지면 재귀 호출 과정이 잘 그려지지 않는다. 이번 문제는 풀면서 재귀 과정을 그림으로 그려가며 진행했지만 오히려 더 복잡했다. 그래서 글로 정리를 하면서 진행했다. 프로그래머스 재귀 관련 문제를 풀면서 다양한 케이스에 적응해야겠다.

배운점


재귀 호출이 진행될 때 outcomes에 값을 어떻게 넣어야 할까 고민을 했다. 그동안 만나왔던 재귀 문제들은 보통 주어진 함수안에서 재귀 호출이 되었기 때문에 지역 변수를 설정하면 재귀 호출마다 초기화 되었다. 하지만 이 문제는 함수안에 재귀 호출을 위한 permutate를 만들어서 진행했기 때문에 재귀 호출중에서도 결과값을 outcomes에 push하면 지역 변수 outcomes로 들어갔다. 이론적으론 알고 있었지만 막상 구현을 하자니 생각치못한 부분이었는데 이 문제를 통해 이런식으로 구현할 수 있다는 것을 배웠다.

profile
즐거운 코딩
post-custom-banner

0개의 댓글