본문 바로가기
Study/Algorithm

[코테 챌린지] 8일차. 빙고

by _YUJIN_ 2024. 8. 12.
빙고 게임은 다음과 같은 방식으로 이루어진다.
먼저 아래와 같이 25개의 칸으로 이루어진 빙고판에 1부터 25까지 자연수를 한 칸에 하나씩 쓴다.
다음은 사회자가 부르는 수를 차례로 지워나간다. 예를 들어 5, 10, 7이 불렸다면 이 세 수를 지운 뒤 빙고판의 모습은 다음과 같다.
차례로 수를 지워가다가 같은 가로줄, 세로줄 또는 대각선 위에 있는 5개의 모든 수가 지워지는 경우 그 줄에 선을 긋는다.
이러한 선이 세 개 이상 그어지는 순간 "빙고"라고 외치는데, 가장 먼저 외치는 사람이 게임의 승자가 된다.
철수는 친구들과 빙고 게임을 하고 있다. 철수가 빙고판에 쓴 수들과 사회자가 부르는 수의 순서가 주어질 때, 사회자가 몇 번째 수를 부른 후 철수가 "빙고"를 외치게 되는지를 출력하는 프로그램을 작성하시오.

첫째 줄부터 다섯째 줄까지 빙고판에 쓰여진 수가 가장 위 가로줄부터 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 여섯째 줄부터 열째 줄까지 사회자가 부르는 수가 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 빙고판에 쓰여진 수와 사회자가 부르는 수는 각각 1부터 25까지의 수가 한 번씩 사용된다.

📌 문제 탐색하기 

우리가 문제를 이해해가는 과정을 작성하시면 됩니다.
- 문제에서 구해야 하는 최종 정답은 무엇인지 탐색한 과정
- 그 정답을 구하기 위해 어떻게 코드를 구현해야 할지 고민한 과정
- 문제에 들어오는 범위를 파악하며 어떤 알고리즘을 쓸 수 있을지 고민해 가는 과정 등을 작성해주시면 됩니다.

알고리즘 선택

  • 각 숫자가 불릴 때마다 빙고판에서 해당 숫자를 찾고, 전체 빙고판을 탐색하여 빙고 여부를 확인하려고 했지만, 이건 비효율적이라고 생각했다. 
  • 그래서 빙고판에서 숫자의 위치를 저장할 때, 딕셔너리를 사용하여 숫자와 그 위치를 매핑하는 방식을 사용했다. 딕셔너리는 특정 숫자의 위치를 시간복잡도 O(1)에 찾을 수 있다. 숫자가 불릴 때마다 빙고판을 전체 탐색하지 않고도 해당 숫자의 위치를 빠르게 확인할 수 있기 때문이다.

📌코드 설계하기 

위의 문제 탐색하기에서 고민한 과정을 토대로 문제 풀이에 대한 실마리를 잡으셨을 것 같습니다.
이제 문제 풀이를 본격적으로 하기 전, 이 문제를 풀기 위한 로드맵을 그려보겠습니다.
어떤 순서로 코드를 작성해야 할지, 어떤 함수들을 작성해야 할지 등을 작성해주시면 됩니다.
처음에는 어려울 수 있지만, 문제를 풀기 전 미리 지도를 그린다라는 생각으로 적어나가 보시면 좋을 것 같습니다 :)
  1. 빙고판에 해당하는 숫자들을 입력받고, 사회자가 부르는 숫자들을 입력받기.
  2. position 딕셔너리를 사용하여 각 숫자가 빙고판에서 어느 위치에 있는지를 저장.
  3. 사회자가 부른 숫자를 빙고판에서 찾아 해당 위치의 숫자를 0으로 바꾼다.
  4. 현재 빙고판에서 몇 개의 빙고가 완성되었는지 확인하고 3개 이상의 빙고가 완성되면 그 시점의 순서를 출력하고 종료.

📌 시도 회차 수정 사항 (Optional)

- 무문별하게 “맞았습니다”가 나올때 까지 수정하는 형태의 문제 풀이를 반복하면 , 내가 어떤 실수를 해서 해당 문제를 틀렸는지 모르게 됩니다.
- 틀렸습니다를 받았다면 왜 틀렸는지 고민해보고 , 어떻게 수정할 수 있는지 고민하는 과정을 작성해주시면 됩니다.
- 위에 내가 세울 설계에서 어떤 부분이 틀렸는지도 함께 점검해보세요
- 한번에 맞출수도 있기 때문에 이 칸은 Optional입니다.

📌정답 코드

def check_bingo(board):
    bingo_count = 0
    
    # 행 체크
    for row in board:
        if sum(row) == 0:
            bingo_count += 1
    
    # 열 체크
    for col in range(5):
        if sum(board[row][col] for row in range(5)) == 0:
            bingo_count += 1
    
    # 대각선 체크
    if sum(board[i][i] for i in range(5)) == 0:
        bingo_count += 1
    
    if sum(board[i][4-i] for i in range(5)) == 0:
        bingo_count += 1
    
    return bingo_count

def main():
    board = []
    for _ in range(5):
        board.append(list(map(int, input().split())))
    
    numbers = []
    for _ in range(5):
        numbers.extend(list(map(int, input().split())))
    
    position = {}
    for i in range(5):
        for j in range(5):
            position[board[i][j]] = (i, j)
    
    for turn, number in enumerate(numbers):
        if number in position:
            i, j = position[number]
            board[i][j] = 0  # 숫자 지우기
            
            if check_bingo(board) >= 3:
                print(turn + 1)
                break

if __name__ == "__main__":
    main()
반응형