프로그래머스 Level 2 혼자서 하는 틱택토

2023. 3. 14. 14:40알고리즘/문제

혼자서 하는 틱택토

출처 : 프로그래머스

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

 

프로그래머스

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

programmers.co.kr

이 포스트는 광고 게시가 없는 비상업적, 비영리적 포스트임을 알려드립니다.

 

문제가 시간 효율적으로 줄이기 위한 고민이라거나 알고리즘 수준 or 선택의 고민이라는 느낌은 들지 않아 아쉬웠습니다.
혹 다른 멋진 풀이법이 있다면 참고하고 공부하고 싶습니다.

풀이

class Solution {
    fun solution(board: Array<String>): Int {
        var cntO = 0
        var cntX = 0
        board.forEach {
            it.forEach { c ->
                if (c == 'O') cntO++
                else if (c == 'X') cntX++
            }
        }
        if (cntX > cntO) return 0
        if (cntO > cntX + 1) return 0
        
        // 승자가 O 일 때 
        if (checkWin('O', board) && cntO <= cntX) return 0
        
        // 승자가 X 일 때
        if (checkWin('X', board) && cntO > cntX) return 0

        return 1
    }
    
	// 승자 체크 함수
    fun checkWin(winner: Char, board: Array<String>): Boolean {
        val w: Boolean = wCheck(winner, board)
        val h: Boolean = hCheck(winner, board)
        val d: Boolean = dCheck(winner, board)
        if (w || h || d) return true
        return false
    }

	// 가로 승리 체크 함수
    fun wCheck(winner: Char, board: Array<String>): Boolean {
        for (i in 0..2) {
            var cnt = 0
            for (j in 0..2) {
                if (board[i][j] == winner) cnt++
            }
            if(cnt == 3) return true
        }
        return false
    }

	// 세로 승리 체크 함수
    fun hCheck(winner: Char, board: Array<String>): Boolean {
        for (j in 0..2) {
            var cnt = 0
            for (i in 0..2) {
                if (board[i][j] == winner) cnt++
            }
            if(cnt == 3) return true
        }
        return false
    }

	// 대각선 승리 체크 함수
    fun dCheck(winner: Char, board: Array<String>): Boolean {
        var b1 = true
        var b2 = true
        for (i in 0..2) {
            if (board[i][i] != winner) b1 = false
            if (board[2 - i][i] != winner) b2 = false
        }
        return b1 || b2
    }
}


저는 

1. 개수 먼저 파악
2. O가 승자일 때 X가 O와 수가 같으면 실패
3. X가 승자일 때 O가 X보다 많으면 실패

단순하게 3개의 경우를 나눠 풀었습니다.

승자일 때를 판단하는 건 가로, 세로, 대각을 나누어 판단하고 셋 중 하나라도 연속된 3개의 경우가 있으면 승리 조건이라고 본 후에 개수를 판단합니다.

 

알고리즘적으로 특별하게 볼 만한 건 없습니다. 

이상입니다.