presentation
presentation

숫자 야구

October 01, 2019 • ☕️ 2 min read
algorithm/programmers

문제 설명

숫자 야구 게임이란 2명이 서로가 생각한 숫자를 맞추는 게임입니다. 게임해보기

각자 서로 다른 1~9까지 3자리 임의의 숫자를 정한 뒤 서로에게 3자리의 숫자를 불러서 결과를 확인합니다. 그리고 그 결과를 토대로 상대가 정한 숫자를 예상한 뒤 맞힙니다.

  • 숫자는 맞지만, 위치가 틀렸을 때는 볼
  • 숫자와 위치가 모두 맞을 때는 스트라이크
  • 숫자와 위치가 모두 틀렸을 때는 아웃

예를 들어, 아래의 경우가 있으면

A : 123 B : 1스트라이크 1볼. A : 356 B : 1스트라이크 0볼. A : 327 B : 2스트라이크 0볼. A : 489 B : 0스트라이크 1볼.

이때 가능한 답은 324와 328 두 가지입니다.

질문한 세 자리의 수, 스트라이크의 수, 볼의 수를 담은 2차원 배열 baseball이 매개변수로 주어질 때, 가능한 답의 개수를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 질문의 수는 1 이상 100 이하의 자연수입니다.
  • baseball의 각 행은 [세 자리의 수, 스트라이크의 수, 볼의 수] 를 담고 있습니다.

입출력 예

baseball return
[[123, 1, 1], [356, 1, 0], [327, 2, 0], [489, 0, 1]] 2

입출력 예 설명

문제에 나온 예와 같습니다.

출처

풀이 과정

처음에 문제가 이해가 안 됐다. 읽다보니 아 그렇구나 싶었다. 분명 카테고리는 완전탐색이니 완전탐색으로 풀어야 하는데, 뭘 어쩌란 말인지 한참 고민했다.

baseball 인자로 주어진 숫자들과 스트라이크, 볼의 조건을 가지고 어떤 숫자를 유추해내는 문제인가 생각했다. 123이 1스트라이크 1볼일 때 각 자릿수와 숫자에 대해서 확률을 쌓아가는 건가? 하고 생각했다.

답을 못 찾겠어서 그냥 남의 풀이를 찾아봤다.

문제를 푸는 방법은 이랬다.

  1. 3자리 숫자가 주어진다.
  2. 이 숫자가 주어진 baseball 인자와 같은 조건을 내어야 한다.

만약 437이라는 숫자가 있을 때 baseball인자에 있는 숫자들을 437과 다 비교해서 스트라이크와 볼의 갯수가 일치하는지 확인하는 문제인 것이다.

function solution(baseball) {
  var answer = 0;

  for (let i = 123; i <= 987; i++) {
    const strN = i.toString();

    if (~strN.indexOf('0')) continue;
    if (strN[0] === strN[1] || strN[1] === strN[2] || strN[0] === strN[2]) continue;

    for (let j = 0; j < baseball.length; j++) {
      const strB = baseball[j][0].toString();

      let strike = 0, ball = 0;

      if (strN[0] === strB[0]) strike++;
      if (strN[1] === strB[1]) strike++;
      if (strN[2] === strB[2]) strike++;
      if (strike !== baseball[j][1]) break;

      if (strN[0] === strB[1] || strN[0] === strB[2]) ball++;
      if (strN[1] === strB[0] || strN[1] === strB[2]) ball++;
      if (strN[2] === strB[0] || strN[2] === strB[1]) ball++;
      if (ball !== baseball[j][2]) break;

      if (j === baseball.length - 1) answer++;
    }
  }

  return answer;
}