(Swift) Programmers 혼자서 하는 틱택토

SteadySlower·2023년 7월 14일
0

Coding Test

목록 보기
273/305

문제 링크

문제 풀이 아이디어

시간 복잡도

틱택토는 3 * 3 배열 안에서 이루어지는 게임이므로 시간복잡도는 고려할 필요가 전혀 없습니다.

0을 리턴하는 케이스 나누기

우리에게 주어진 정보는 틱택토가 끝난 결과입니다. 따라서 O와 X가 놓여진 순서는 따지지 않고 갯수와 승패를 가지고 케이스를 나누면 되겠습니다.

갯수에 관한 케이스

틱택토는 O가 먼저 두고 X가 나중에 둡니다. 따라서 실수가 없었다면 O와 X의 갯수가 동일하거나 O가 X보다 1개 더 많아야 합니다.

승패에 대한 케이스

  1. 승자는 1명 뿐입니다. 둘 다 승리하는 경우는 없습니다.
  2. O가 승리한 경우에는 O가 마지막에 두고 끝납니다. 따라서 O의 갯수가 1개 더 많아야 합니다.
  3. X가 승리한 경우에는 X가 마지막에 두고 끝납니다. 따라서 O와 X의 갯수가 동일해야 합니다.

코드

func solution(_ board:[String]) -> Int {
    
    // subscript로 접근하게 편하도록 이차원 배열[[String]]으로 바꾸어 준다
    let board = board.map { $0.map { String($0) } }
    
    // O와 X 갯수 세기
    var oCount = 0
    var xCount = 0
    
    for i in 0..<3 {
        for j in 0..<3 {
            if board[i][j] == "O" {
                oCount += 1
            } else if board[i][j] == "X" {
                xCount += 1
            }
        }
    }
    
    // 이긴 사람 정하기
    var oWin = false
    var xWin = false
    
    // 가로, 세로 확인
    for i in 0..<3 {
        if (board[i][0] == board[i][1]) && (board[i][1] == board[i][2]) {
            if board[i][0] == "O" {
                oWin = true
            } else if board[i][0] == "X" {
                xWin = true
            }
        }
        
        if (board[0][i] == board[1][i]) && (board[1][i] == board[2][i]) {
            if board[0][i] == "O" {
                oWin = true
            } else if board[0][i] == "X" {
                xWin = true
            }
        }
    }
    
    // 대각선 확인
    if (board[0][0] == board[1][1]) && (board[1][1] == board[2][2]) {
        if board[0][0] == "O" {
            oWin = true
        } else if board[0][0] == "X" {
            xWin = true
        }
    } else if (board[0][2] == board[1][1]) && (board[1][1] == board[2][0]) {
        if board[0][2] == "O" {
            oWin = true
        } else if board[0][2] == "X" {
            xWin = true
        }
    }
    
    // O와 X의 갯수가 같거나 O가 1개 많다.
    if !(0...1).contains(oCount - xCount) {
        return 0
    // O와 X가 동시에 이기면 안된다.
    } else if oWin && xWin {
        return 0
    // O가 이긴 경우, O가 X보다 1개 많아야 한다.
    } else if oWin && (oCount != xCount + 1) {
        return 0
    // X가 이긴 경우, O와 X의 갯수가 같아야 한다.
    } else if xWin && (oCount != xCount) {
        return 0
    }
    
    return 1
}
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글