
const fs = require('fs');
const path = process.platform === 'linux' ? '/dev/stdin' : 'input.txt';
const inputs = fs.readFileSync(path).toString().trim().split('\n');
const getBingo = (map) => {
const ansPiece = [];
if (new Set([map[0], map[1], map[2]]).size === 1) ansPiece.push(map[0]);
if (new Set([map[3], map[4], map[5]]).size === 1) ansPiece.push(map[3]);
if (new Set([map[6], map[7], map[8]]).size === 1) ansPiece.push(map[6]);
if (new Set([map[0], map[3], map[6]]).size === 1) ansPiece.push(map[0]);
if (new Set([map[1], map[4], map[7]]).size === 1) ansPiece.push(map[1]);
if (new Set([map[2], map[5], map[8]]).size === 1) ansPiece.push(map[2]);
if (new Set([map[0], map[4], map[8]]).size === 1) ansPiece.push(map[0]);
if (new Set([map[2], map[4], map[6]]).size === 1) ansPiece.push(map[2]);
return ansPiece.filter((it) => it !== '.');
};
for (const input of inputs) {
if (input === 'end') break;
let xCnt = 0;
let oCnt = 0;
let dotCnt = 0;
for (const piece of input) {
if (piece === 'O') oCnt += 1;
else if (piece === 'X') xCnt += 1;
else dotCnt += 1;
}
const ansPiece = getBingo(input);
if (dotCnt === 0) {
if (xCnt !== 5 || oCnt !== 4) console.log('invalid');
else if (new Set(ansPiece).size === 2) console.log('invalid');
else if (ansPiece === 0) console.log('valid');
else if (ansPiece.length === 2) console.log('valid');
else {
if (ansPiece[0] === 'O') console.log('invalid');
else console.log('valid');
}
} //
else {
if (ansPiece.length === 2) console.log('invalid');
else if (ansPiece.length === 1) {
if (ansPiece[0] === 'O' && xCnt === oCnt) console.log('valid');
else if (ansPiece[0] === 'X' && xCnt - oCnt === 1) console.log('valid');
else console.log('invalid');
} else console.log('invalid');
}
}
또 다른 풀이
const fs = require('fs');
const path = process.platform === 'linux' ? '/dev/stdin' : 'input.txt';
const inputs = fs.readFileSync(path).toString().trim().split('\n');
const bingoLines = [
[
[0, 0],
[0, 1],
[0, 2],
],
[
[1, 0],
[1, 1],
[1, 2],
],
[
[2, 0],
[2, 1],
[2, 2],
],
[
[0, 0],
[1, 0],
[2, 0],
],
[
[0, 1],
[1, 1],
[2, 1],
],
[
[0, 2],
[1, 2],
[2, 2],
],
[
[0, 0],
[1, 1],
[2, 2],
],
[
[0, 2],
[1, 1],
[2, 0],
],
];
const getBingoCnt = (map, target) => {
let cnt = 0;
for (const bingoLine of bingoLines) {
let isBingo = true;
for (const [x, y] of bingoLine) {
if (map[x][y] !== target) isBingo = false;
}
if (isBingo) cnt += 1;
}
return cnt;
};
for (const input of inputs) {
if (input === 'end') continue;
const oCnt = input.split('O').length - 1;
const xCnt = input.split('X').length - 1;
const map = [input.slice(0, 3).split(''), input.slice(3, 6).split(''), input.slice(6, 9).split('')];
const xBingoCnt = getBingoCnt(map, 'X');
const oBingoCnt = getBingoCnt(map, 'O');
// 게임이 종료된 상태 : 반드시 x가 1줄이거나 0줄 달성, o는 0줄 달성
if (oCnt === 4 && xCnt === 5 && oBingoCnt === 0) console.log('valid');
// x가 이김 -> 반드시 x가 한줄로 이겨야 함
else if (xCnt - oCnt === 1 && oBingoCnt === 0 && xBingoCnt === 1) console.log('valid');
// console.log('반드시 o가 한줄로 이겨야 하고 x는 이길 수 없는 상태여야 함');
else if (oCnt === xCnt && xBingoCnt === 0 && oBingoCnt === 1) console.log('valid');
else console.log('invalid');
}
⏰ 소요한 시간 : -
풀어볼법한 시뮬레이션 문제라서 두번 풀이했다.
첫 번째 풀이는 빙고를 세는 과정이 깔끔하고
두번째 풀이는 정답을 내는 과정이 깔끔해서… 둘다 가져왔음
중요한점만 뽑아보자면
이 문제는 1. 빙고의 개수를 세고, 2. 빙고의 개수에 따라 valid 한지, invalid 한지를 출력하면 된다.
빙고의 개수 세기
3x3 빙고기 때문에 모든 빙고의 경우의 수를 좌표로 기억할 수 있다. 따라서 아래와 같이 빙고가 될 수 있는 8가지 경우를 하드코딩해서 확인해줄 수 있다.
지금은 O, X 둘을 구분짓지 않고 리턴하지만 객체형태로 다루는 것이 다음 로직을 설계하는데에 편리하다.
const getBingo = (map) => {
const ansPiece = [];
// const ansPiece = { oCnt : 0, xCnt : 0}
if (new Set([map[0], map[1], map[2]]).size === 1) ansPiece.push(map[0]);
if (new Set([map[3], map[4], map[5]]).size === 1) ansPiece.push(map[3]);
if (new Set([map[6], map[7], map[8]]).size === 1) ansPiece.push(map[6]);
if (new Set([map[0], map[3], map[6]]).size === 1) ansPiece.push(map[0]);
if (new Set([map[1], map[4], map[7]]).size === 1) ansPiece.push(map[1]);
if (new Set([map[2], map[5], map[8]]).size === 1) ansPiece.push(map[2]);
if (new Set([map[0], map[4], map[8]]).size === 1) ansPiece.push(map[0]);
if (new Set([map[2], map[4], map[6]]).size === 1) ansPiece.push(map[2]);
return ansPiece.filter((it) => it !== '.');
};
빙고의 개수에 따라 valid, invalid 판별하기
틱택토 게임의 valid 조건은 다음과 같다.
해당 벨리데이션만 잘 지켜주면된다.