프로그래머스의 완전 탐색 문제 3번째 문제이다. 역시 이번에도 완전 탐색에 좀 더 익숙해지기 위해 풀어본 문제이다. Level 2 중에서는 가장 풀이한 사람이 적은 문제였다.

처음에는 주어진 값을 계산해서 맞는 답을 찾아낼 수 있지 않을까 했는데, 그런 방법 같은 건 떠오르지 않았다.. 컴퓨터가 사람처럼 생각할 수 있다면 얼마나 좋을까 😂

그래서 하나씩 숫자를 증가하면서, 이 숫자가 답이라면 주어진 값들과 결과가 일치해야 하기 때문에 숫자 야구 게임을 해보고 그 결과가 주어진 값과 결과가 일치하는지 확인하면서 답을 찾아가기로 했다.

때문에 여기에 필요한 기능은 아래와 같을 것이다.

  • 증가한 숫자가 조건과 맞는지 확인하는 기능
  • 숫자 야구 게임을 하는 기능
  • 결과를 비교해서 주어진 값(baseball)과 결과가 일치하는지 확인하는 기능

풀이

숫자를 하나씩 비교하기 위해서 시작 값은 123, 끝 값은 987으로 두고 for문으로 한번씩 비교해보기로 했다. 시작이 123이고 끝이 987인 이유는, 1 ~ 9의 숫자가 세자리로 중복되지 않아야하기 때문이다.

하지만 숫자를 증가시키다보면 131처럼 중복되는 값이 나올 수 있고, 130처럼 범위에 없는 값이 나올 수 있기 때문에 이에 대해 판별하는 isInvalidNumber()를 작성해 이 부분은 숫자 야구 게임을 진행하지 않았다.

나머지 유효한 값에는 해당 값이 답이라고 할 때, 결과가 주어진 값과 동일한지 숫자 야구 게임을 진행해 확인한다. 만약 같은 자리에 같은 수가 있으면 strike를 증가시키고 같은 수가 포함되어있기만 한다면 ball을 증가시킨다. 이 때 정답으로 예측한 값이 모든 주어진 값과 결과가 같았다면 answer 값을 증가시켜서 가능한 답의 개수를 찾는다.

코드

JavaScript

function solution(baseball) {
  let answer = 0;

  for (let i = 123; i < 988; i++) {
    if (isInvalidNumber(i)) continue;
    let possibleFlag = false;

    for (let proposal of baseball) {
      const [strike, ball] = baseballGame(proposal[0], i);

      if (proposal[1] !== strike || proposal[2] !== ball) {
        possibleFlag = false;
        break;
      }

      possibleFlag = true;
    }

    if (possibleFlag) answer++;
  }

  return answer;
}

function isInvalidNumber(numbers) {
  const numberArray = numbers.toString().split('');

  if (numberArray[1] === '0' || numberArray[2] === '0') return true;

  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      if (j === i) continue;
      if (numberArray[i] === numberArray[j]) return true;
    }
  }

  return false;
}

function baseballGame(proposal, answer) {
  const answerArray = answer.toString().split('');
  const proposalArray = proposal.toString().split('');

  return proposalArray.reduce(
    (result, number, index) => {
      if (number === answerArray[index]) {
        result[0]++;
        return result;
      }

      if (answerArray.includes(number)) {
        result[1]++;
        return result;
      }

      return result;
    },
    [0, 0],
  );
}