[프로그래머스] 숫자 야구 JavaScript
프로그래머스의 완전 탐색 문제 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],
);
}