문제 요약
입력
11 12 2 24 10
16 1 13 3 25
6 20 5 21 17
19 4 8 14 9
22 15 7 23 18
5 10 7 16 2
4 22 8 17 13
3 18 1 6 25
12 19 23 14 21
11 24 9 20 15
출력
15
문제 분석
문제 설계
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
const obj = {};
const line = input.map((nums) => nums.split(' ').map(Number));
const half = line.length / 2;
const firstArr = line.splice(0, half);
const callNumbers = line.splice(-half).flatMap((item) => item);
for (let row = 0; row < 5; row++) {
for (let col = 0; col < 5; col++) {
const key = firstArr[row][col];
obj[key] = [row, col];
}
}
const rowArr = Array(5).fill(0);
const colArr = Array(5).fill(0);
const rowCompleted = Array(5).fill(false);
const colCompleted = Array(5).fill(false);
let diagonalLeft = 0;
let diagonalRight = 0;
let diagonalLeftCompleted = false;
let diagonalRightCompleted = false;
let count = 0;
for (let i = 0; i < callNumbers.length; i++) {
const luckNumber = callNumbers[i];
if (!(luckNumber in obj)) continue;
const [row, col] = obj[luckNumber];
rowArr[row]++;
colArr[col]++;
if (row === col) {
diagonalLeft++;
}
if (row + col === 4) {
diagonalRight++;
}
if (rowArr[row] === 5 && !rowCompleted[row]) {
count++;
rowCompleted[row] = true;
}
if (colArr[col] === 5 && !colCompleted[col]) {
count++;
colCompleted[col] = true;
}
if (diagonalLeft === 5 && !diagonalLeftCompleted) {
count++;
diagonalLeftCompleted = true;
}
if (diagonalRight === 5 && !diagonalRightCompleted) {
count++;
diagonalRightCompleted = true;
}
if (count >= 3) {
console.log(i + 1);
break;
}
}
내 빙고, 사회자 빙고를 분리하는 로직 map, splice, flatMap
const line = input.map((nums) => nums.split(' ').map(Number));
const half = line.length / 2;
const firstArr = line.splice(0, half); // 내 빙고판
const callNumbers = line.splice(-half).flatMap((item) => item);
내 빙고의 좌표를 정리하는 로직 for 문
const obj = {};
//...
for (let row = 0; row < 5; row++) {
for (let col = 0; col < 5; col++) {
const key = firstArr[row][col];
obj[key] = [row, col];
}
}
그러면 아래와 같은 꼴로 담긴다.

빙고를 판단하는 로직 for,Array(n).fill(k)

빙고가 되는 조건을 정리해보자.핵심은 일차원 배열로 보는 것이다.
빙고 한 줄(5개 숫자)를 1로 보았을 때
인데, 이를 일차원 배열로 정리를 하는것이다.
가로줄 기준(세로줄 동일)으로 보자면 [0,0,0,0,0]가 초기값일 것이다.
예를 들어 사회자가 11,12,2,24,10을 연속적으로 불렀다고 가정해보자
사회자: 번호 11!
나: [1,0,0,0,0]
사회자: 번호 12!
나:[2,0,0,0,0]
이런식으로 해당 줄에서 일치하는 숫자가 계속 불러지니 결국 5번째 숫자에 0번째 인덱스의 값이 5가 될 것이고 이게 원빙고라는 것이다!
그럼 이를 로직에 적용해보자. 로직별로 주석을 달아놨다!
const rowArr = Array(5).fill(0);
const colArr = Array(5).fill(0);
const rowCompleted = Array(5).fill(false);
const colCompleted = Array(5).fill(false);
let diagonalLeft = 0;
let diagonalRight = 0;
let diagonalLeftCompleted = false;
let diagonalRightCompleted = false;
let count = 0;
for (let i = 0; i < callNumbers.length; i++) {
const luckNumber = callNumbers[i];
// 숫자가 빙고판에 있는지 확인
if (!(luckNumber in obj)) continue;
const [row, col] = obj[luckNumber]; // 사회자가 하나씩 불러줄 테니 그렇게 만들어 봅시다.
rowArr[row]++;
colArr[col]++;
if (row === col) {
diagonalLeft++;
}
if (row + col === 4) {
diagonalRight++;
}
// 행 빙고 체크
if (rowArr[row] === 5 && !rowCompleted[row]) {
count++;
rowCompleted[row] = true;
}
// 열 빙고 체크
if (colArr[col] === 5 && !colCompleted[col]) {
count++;
colCompleted[col] = true;
}
// 대각선 왼쪽 빙고 체크
if (diagonalLeft === 5 && !diagonalLeftCompleted) {
count++;
diagonalLeftCompleted = true;
}
// 대각선 오른쪽 빙고 체크
if (diagonalRight === 5 && !diagonalRightCompleted) {
count++;
diagonalRightCompleted = true;
}
// 3개의 빙고가 완성되면 출력
if (count >= 3) {
console.log(i + 1);
break;
}
}
주의해야할 점은
rowCompleted, colCompleted 배열과 diagonalLeftCompleted, diagonalRightCompleted 플래그를 사용해 이미 확인된 행, 열, 대각선의 빙고를 다시 카운트하지 않는 로직을 세워줘야한다.===3 을 빙고 조건을 걸면 한계가 있다.>=3로 해줘야한다.결론