몸과 마음이 건전한 SW 개발자

프로그래머스 [Lv. 2] 혼자서 하는 틱택토 {언어 : Python} [반례 포함] 본문

알고리즘

프로그래머스 [Lv. 2] 혼자서 하는 틱택토 {언어 : Python} [반례 포함]

스위태니 2024. 4. 12. 00:28

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/160585

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

정답 코드

def solution(board):
    # O의 개수 X의 개수
    cntO = 0
    cntX = 0
    
    # 누가 이겼는지
    winO = [0]
    winX = [0]
    
    def whoWin(who):
        if who == "X":
            winX[0] += 1
        else:
            winO[0] += 1
        return
    
    #개수 새기
    for i in range(3):
        for j in range(3):
            tmp = board[i][j]
            if tmp == ".":
                continue
            elif tmp == "X":
                cntX += 1
            else:
                cntO += 1
    
    # 가로 탐색
    for i in range(3):
        cnt = 1
        who = board[i][0]
        if who == ".":
            continue
        for j in range(1, 3):
            nextWho = board[i][j]
            if who == nextWho:
                cnt += 1
        if cnt == 3:
            whoWin(who)
    
    # 세로 탐색
    for l in range(3):
        cnt = 1
        who = board[0][l]
        if who == ".":
            continue
        for m in range(1, 3):
            nextWho = board[m][l]
            if who == nextWho:
                cnt += 1
        if cnt == 3:
            whoWin(who)
                
    # 대각선 탐색
    cross = board[1][1]
    if cross != ".":
        if cross == board[0][0] and cross == board[2][2]:
            whoWin(cross)
        if cross == board[0][2] and cross == board[2][0]:
            whoWin(cross)
    
    answer = 0
    # 가능한지 판단
    if winO[0] == 1 and winX[0] == 0 and cntO == cntX + 1:
        answer = 1
    elif winX[0] == 1 and winO[0] == 0 and cntX == cntO:
        answer = 1
    elif cntO == 0 and cntX == 0:
        answer = 1
    elif winO[0] == 0 and winX[0] == 0:
        if cntO == cntX or cntO == cntX + 1:
            answer = 1
    elif winO[0] == 2 and cntO == 5 and cntX == 4:
        answer = 1
        
    return answer

풀이 방법

  1. X와 O의 개수를 탐색
  2. 가로 세로 대각선을 순회하여 누가 몇 번 이겼는지 탐색
  3. 5가지의 경우만 가능한 경우로 판단된다.
    1. O의 빙고 개수가 1인 경우 X는 0이어야 하며 선공이므로 X보다 1 많아야 한다.
    2. X의 빙고 개수가 1인 경우 O는 0이어야 하며 후공이므로 O와 개수가 같아야 한다.
    3. 아무것도 없는 경우
    4. 아무도 이기지 못한 경우
      1. X와 O의 개수가 같을 수도 있다.
      2. X가 둬야 하는 차례에 끝난 경우 O보다 1개 적을 수 있다.
    5. 반례의 상황과 같다.
  4. 위의 경우의 수에서 멈추지 않는 경우 answer는 초기값인 0을 반환한다.

반례

board: ["OXO", "XOX", "OXO"]
result: 1

느낀점

  • 노가다 문제인데 반례를 떠올리지 못하면 못 푼다...
  • 아쉽다.