[알고리즘] 프로그래머스 Lv2 혼자서 하는 틱택토

Sieun Dorothy Lee·2024년 1월 19일
0

문제

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

풀이과정

규칙을 어기는 경우에 대해서 생각해보았다.
다음과 같은 4가지 경우가 정해졌고
그것을 코드로 그대로 구현했다.

올바른 게임이 아닌 경우 (게임은 항상 O가 먼저 시작한다)
1. O의 개수 > X의 개수+1
2. O의 개수 < X의 개수
3. O가 한 줄이 되는 경우가 있는데(O가 승리하는 경우), O가 X보다 한 개 더 많지 않은 경우
4. X가 한 줄이 되는 경우가 있는데(X가 승리하는 경우), O와 X의 개수가 같지 않은 경우

Lv2의 다른 문제에 비해 쉬운 편이라고 생각이 된다.

코드

def solution(board):
    cnt_o, cnt_x = 0, 0
    # 숫자로 기록하는 보드 => O: 1, X: 10, . = 0
    n_board = [[0] * 3 for _ in range(3)]

    for i in range(3):
        for j in range(3):
            if board[i][j] == 'O':
                cnt_o += 1
                n_board[i][j] = 1
            elif board[i][j] == 'X':
                cnt_x += 1
                n_board[i][j] = 10

    if cnt_o < cnt_x or cnt_o > cnt_x+1:
        return 0
    
    for k in range(3):
        if (sum(n_board[k]) == 3 or sum(list(zip(*n_board))[k]) == 3) and cnt_o != cnt_x + 1:
                return 0
        if (sum(n_board[k]) == 30 or sum(list(zip(*n_board))[k]) == 30) and cnt_o != cnt_x:
                return 0

        
    if n_board[0][0] + n_board[1][1] + n_board[2][2] == 3 and cnt_o != cnt_x + 1:
        return 0
    
    if n_board[0][0] + n_board[1][1] + n_board[2][2] == 30 and cnt_o != cnt_x:
        return 0
    
    if n_board[0][2] + n_board[1][1] + n_board[2][0] == 3 and cnt_o != cnt_x + 1:
        return 0

    if n_board[0][2] + n_board[1][1] + n_board[2][0] == 30 and cnt_o != cnt_x:
        return 0
            
    return 1


board = ["O.X", ".O.", "..X"]
board = ["OOO", "...", "XXX"]
board = ["...", ".X.", "..."]
board = ["...", "...", "..."]
print(solution(board))

다른 사람의 풀이

# Check if there is a winning row, column, or diagonal
def check_win(player, board):
    # Check rows
    for i in range(3):
        if all(cell == player for cell in board[i]):
            return True

    # Check columns
    for j in range(3):
        if all(board[i][j] == player for i in range(3)):
            return True

    # Check diagonals
    if all(board[i][i] == player for i in range(3)):
        return True
    if all(board[i][2-i] == player for i in range(3)):
        return True

    return False

def solution(board):
    num_x = sum(row.count('X') for row in board)
    num_o = sum(row.count('O') for row in board)

    if num_x - num_o > 0 or abs(num_x - num_o) > 1:
        return 0

    elif (check_win('O', board) and num_x != num_o - 1) or (check_win('X', board) and num_x != num_o):
        return 0

    return 1

이기는 경우를 판별하는 함수를 따로 빼서 작성한 덕분에 코드가 깔끔해졌다.
check_win 함수에서 all 내장함수를 쓴 점이 파이써닉하다!

profile
성장하는 중!

0개의 댓글