[BOJ-실버4] 2578: 빙고

아이엠강욱·2023년 4월 29일
0

코딩테스트

목록 보기
1/23

해당 문제를 확인하시고 싶으면 아래 링크를 통해 확인해주세요!
https://www.acmicpc.net/problem/2578


나의 오답코드

"""
백준 2578번: 빙고
https://www.acmicpc.net/problem/2578

오답이유) 나도 진짜 잘 모르겠다 도대체
"""
import sys
input = sys.stdin.readline

matrix = [list(map(int, input().split())) for _ in range(5)]   # 빙고판
try_bingo = [list(map(int, input().split())) for _ in range(5)]   # 사회자가 부르는 수
result = 0
idx = 0
bingoCount = 0

# 빙고판에 해당 번호가 있는지 확인하고 x,y 좌표에 해당하는 부분 X처리
def find_number(matrix, value):
    dx, dy = 0, 0

    for a in range(5):
        for b in range(5):
            if matrix[a][b] == value:
                matrix[a][b] = 0
                dx = a
                dy = b
                break

    return dx, dy


def check_bingo(matrix, x, y):
    bgCount = 0
    crossCheckResult = False

    rowCheckResult = row_check(matrix, x)   # 가로 확인
    colCheckResult = col_check(matrix, y)   # 세로 확인

    # x=y이거나 x+y가 4이면 대각선 확인
    if x == y:
        crossCheckResult = cross_check(matrix, 'equal')
    elif x + y == 4:
        crossCheckResult = cross_check(matrix, 'plus')

    if rowCheckResult == True:
        bgCount += 1
    if colCheckResult == True:
        bgCount += 1
    if crossCheckResult == True:
        bgCount += 1

    return bgCount

def row_check(matrix, x):
    checkRowBingo = True
    for i in range(5):
        if matrix[x][i] != 0:
            checkRowBingo = False
            break
    
    return checkRowBingo
        

def col_check(matrix, y):
    checkColBingo = True
    for i in range(5):
        if matrix[i][y] != 0:
            checkColBingo = False
            break

    return checkColBingo

def cross_check(matrix, option):
    checkCrossBingo = True
    
    if option == 'equal':
        for i in range(5):
            if matrix[i][i] != 0:
                checkCrossBingo = False
    elif option == 'plus':
        for i in range(5):
            if matrix[i][4-i] != 0:
                checkCrossBingo = False
    
    return checkCrossBingo


for i in range(5):
    for j in range(5):
        idx += 1
        dx, dy = find_number(matrix, try_bingo[i][j])   # O처리 진행
        
        if idx >= 5:   # 빙고 시작한지 5턴 이상이면
            bingoCount += check_bingo(matrix, dx, dy)
            if bingoCount >= 3:
                result = idx
                break
    if bingoCount >= 3:
        break

print(result)

결과값은 잘 나오는걸 확인할 수 있었다. 어디가 틀렸지 보는데 진짜 어디가 틀린지 감을 1도 못잡겠다.
혹시나 이 게시물을 보시는 분이 계시다면 문제점을 한번 찾아봐주시면 감사하겠습니다....!

하지만 확실한건 하나 알았습니다.
나의 코드가 너무 더럽다는 것을요.....

2시간동안 풀어보고 계속 틀렸다고 백준에서 응답해주니까 구글링으로 다른사람의 코드도 많이 봤는데 볼때마다 내 코드가 진짜 너무 더럽고 보기 싫었습니다...!

생각한 로직은 둘다 확실히 똑같은데 왜 코드는 다른지,,ㅎㅎ
어쨌든 구글링을 통해 내가 배울점이 많은 코드를 찾았다! (이번엔 파이썬 문법적으로..?)

참고한 소스코드 (약간 수정 들어감)

"""
백준 2578번: 빙고
https://www.acmicpc.net/problem/2578

이전에 작업한 코드랑 진짜 로직은 완전 똑같은데.... 왜 틀린지는 잘 모르겠지만
해당 코드는 깔끔하고 배울 부분이 많은거 같아서 참고했다.
"""

def isBingo(arr):
    bgCount = 0

    # (1) 가로 줄 확인
    for row in arr:
        if row.count(0) == 5:   # 해당 행에서 0의 개수가 5개 -> 맞은거임
            bgCount += 1 

    # (2) 세로 줄 확인
    for i in range(5):
        tmp = 0
        for j in range(5):
            if arr[j][i] == 0:
                tmp += 1
        if tmp == 5:
            bgCount += 1

    # (3) 왼쪽->오른쪽 대각선 확인
    tmp2 = 0
    for i in range(5):
        if arr[i][i] == 0:
            tmp2 += 1
    if tmp2 == 5:
        bgCount += 1

    # (4) 오른쪽->왼쪽 대각선 확인
    tmp3 = 0
    for i in range(5):
        if arr[i][4-i] == 0:
            tmp3 += 1
    if tmp3 == 5:
        bgCount += 1

    return bgCount


bingo = [list(map(int, input().split())) for _ in range(5)]   # 빙고판
tutor = []   # 하나씩 부를 숫자

# 사회자가 하나씩 부르는 숫자 1차원 배열로 세팅
for _ in range(5):
    tutor_temp = list(map(int, input().split()))
    for tt in tutor_temp:
        tutor.append(tt)

for idx, num in enumerate(tutor):
    for bg in bingo:   # 빙고판에서 1번째줄부터 확인
        if num in bg:   # 해당 줄에 사회자가 부른 번호가 포함되어 있으면
            bg[bg.index(num)] = 0   # 해당 부분 0으로 UPDATE
            break
    bingoCount = isBingo(bingo)   # 맞은 줄 개수 확인
    if bingoCount >= 3:
        print(idx + 1)
        exit()

내가 작성한 코드보다 확실히 간결해보이긴 하다! 물론 위의 코드보다 더 효율적으로 구현할 수는 있을 거 같은데 그래도 이정도 코드면 충분하다고 판단했다.

이 코드에서 내가 배운점을 한번 쭉 정리해보자!

  • array.count(value): 해당 배열에서 value가 몇 개 있는지 Return
  • enumerate: 인덱스와 값을 같이 받을 수 있는 메서드 (자주 사용될듯?)
  • array.index(value): 해당 배열에서 value가 있는 인덱스 Return

해당 파이썬 문법들을 알았다면 조금 더 간결하게 코드를 작성해볼 수 있었을 거 같습니다!

아직도 내가 왜 틀린지는 모르겠지만.. 졸려서 내가 못찾은걸수도..?
아무튼 오늘은 여기까지 회고하고 시간되면 한번 더 코드 확인해봐야 할거같다!
로직은 그래도 동일하니 그나마 다행....


Reference

profile
블로그 이전했습니다!! https://dev-iamkanguk.tistory.com/ <<- 여기로 오세용!!

0개의 댓글