문제 : https://www.acmicpc.net/problem/2578
빙고 게임은 다음과 같은 방식으로 이루어진다.
25개의 칸으로 이루어진 빙고판에 1부터 25까지 자연수를 한 칸에 하나씩 쓴다.
차례로 수를 지워가다가 같은 가로줄, 세로줄 또는 대각선 위에 있는 5개의 모든 수가 지워지는 경우 그 줄에 선을 긋는다. 이러한 선이 세 개 이상 그어지는 순간 "빙고"라고 외치는데, 가장 먼저 외치는 사람이 게임의 승자가 된다.
철수는 친구들과 빙고 게임을 하고 있다. 철수가 빙고판에 쓴 수들과 사회자가 부르는 수의 순서가 주어질 때, 사회자가 몇 번째 수를 부른 후 철수가 "빙고"를 외치게 되는지를 출력하는 프로그램을 작성하시오.
입력
첫째 줄부터 다섯째 줄까지 빙고판에 쓰여진 수가 가장 위 가로줄부터 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 여섯째 줄부터 열째 줄까지 사회자가 부르는 수가 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 빙고판에 쓰여진 수와 사회자가 부르는 수는 각각 1부터 25까지의 수가 한 번씩 사용된다.
출력
첫째 줄에 사회자가 몇 번째 수를 부른 후 철수가 "빙고"를 외치게 되는지 출력한다.
📌 문제 탐색하기
1. 같은 가로줄, 세로줄 빙고
-> 가로줄 : arr[i][0~4] 값 충족
-> 세로줄 : arr[0~4][i] 값 충족
2. 대각선 빙고
-> arr[i][i] 값 충족
-> arr[i][4-i] 값 충족
3. 1~25번 사회자가 값 호출
-> 중첩 for문으로 같은 배열의 값은 true로 설정
-> 한 줄 빙고될 때마다 count+1
-> count=3일 때 해당 호출 번호 출력
📌 코드 설계하기
1. 입력값 가져오기
-> input=.trim().split("\n")
-> 빙고판 : for(let i=0;i<4;i++){arr.push(input[i].split(" ")}
-> 호출 배열: for(let i=5;i<9;i++){newArray.push(input[i].split(" ")}
2. 순서대로 값 호출
-> 빙고 횟수 : let count=0;
-> for(let i=0;i<25;i++){[arr 배열 중첩 for문으로 호출]}
-> 빙고값 조건을 충족하는 경우 count+1
📌 시도 회차 수정 사항
[1회차]
- check[i]줄에 속한 모든 0~4 배열 값을 충족하는지를 판별하는 함수를 몰라 그냥 노가다로 하나하나 구문을 썼다
- 그리고 그마저도 틀렸다...
- 안 그래도 코드가 너무 지저분해서 고민을 많이 했는데 빙고 판별 함수를 밖으로 빼서 정리하고, 나중에 가져다 쓰는 방식이 깔끔할거 같아서 수정했다.
//실패한 코드
for (let k = 0; k < 25; k++) {
let count = 0;
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (arr[i][j] === newArray[k]) {
check[i][j] = true;
}
if (
(check[i][1] && check[i][2]) ||
(check[i][0] && check[i][3]) ||
(check[0][i] && check[1][i] && check[2][i] && check[3][i]) ||
(check[0][0] && check[1][1] && check[2][2] && check[3][4])
) {
count += 1;
}
if (count >= 3) {
console.log(k + 1);
break;
}
}
}
}
📌 정답 코드
const input = require("fs").readFileSync(0, "utf-8").trim().split("\n");
const arr = [];
const newArray = [];
let check = Array.from({ length: 5 }, () => Array(5).fill(0));
for (let i = 0; i < 5; i++) {
arr.push(input[i].trim().split(" ").map(Number));
}
for (let i = 5; i < 10; i++) {
newArray.push(...input[i].trim().split(" ").map(Number));
}
const checkBingo = () => {
let count = 0;
for (let i = 0; i < 5; i++) {
if (check[i].every((cell) => cell)) count++;
}
for (let j = 0; j < 5; j++) {
if (check.every((row) => row[j])) count++;
}
if (check.every((row, idx) => row[idx])) count++;
if (check.every((row, idx) => row[4 - idx])) count++;
return count;
};
for (let k = 0; k < 25; k++) {
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (arr[i][j] === newArray[k]) {
check[i][j] = true;
}
}
}
if (checkBingo() >= 3) {
console.log(k + 1);
break;
}
}
해설 : https://whydevsaysno.notion.site/126b7e9387e848c48d5cb29a835eb69b
'코딩테스트' 카테고리의 다른 글
[Javascript] 백준 2748 : 피보나치 수 2 (0) | 2025.01.14 |
---|---|
[Javascript] 백준 7568 : 덩치 (0) | 2025.01.12 |
[Javascript] 백준 2947 : 나무 조각 (1) | 2025.01.11 |
[Javascript] 백준 25305 : 커트라인 (0) | 2025.01.09 |
[Javascript] 백준 5635 : 생일 (1) | 2025.01.08 |