-
코딩테스트 / 혼자서 하는 틱택토코딩 테스트/Level 2 2023. 2. 25. 18:16반응형
https://school.programmers.co.kr/learn/courses/30/lessons/160585
이런저런 케이스를 다 생각해서 풀어야 하는 문제...
1. 선공인 O와 후공인 X의 개수가 1 이상 나면 안 된다.
2. O와 X가 동시에 이겨서는 안 된다.
3. O가 이겼을 때 다음 X는 없다. 그러므로 O가 X보다 1개 많아야..
4. X가 이겼을 때 다음 O는 없다. 그러므로 O와 X의 개수가 같아야..코틀린
class Solution { private fun countMarker(board: Array<String>): Pair<Int, Int> { var (oCounter, xCounter) = arrayOf(0, 0) for (line in board) for (each in line) if (each == 'O') oCounter++ else if (each == 'X') xCounter++ return Pair(oCounter, xCounter) } private fun countWin(board: Array<String>): Pair<Int, Int> { var (oWin, xWin) = arrayOf(0, 0) for (i in 0..2) { var (oRow, xRow, oCol, xCol) = arrayOf(0, 0, 0, 0) for (j in 0..2) { when (board[i][j]) { 'O' -> oRow++ 'X' -> xRow++ } when (board[j][i]) { 'O' -> oCol++ 'X' -> xCol++ } } oWin += (if (oRow == 3) 1 else 0) + if (oCol == 3) 1 else 0 xWin += (if (xRow == 3) 1 else 0) + if (xCol == 3) 1 else 0 } var (oCnt1, xCnt1, oCnt2, xCnt2) = arrayOf(0, 0, 0, 0) for (i in 0..2) { oCnt1 += if (board[i][i] == 'O') 1 else 0 xCnt1 += if (board[i][i] == 'X') 1 else 0 oCnt2 += if (board[i][2 - i] == 'O') 1 else 0 xCnt2 += if (board[i][2 - i] == 'X') 1 else 0 } oWin += (if (oCnt1 == 3) 1 else 0) + if (oCnt2 == 3) 1 else 0 xWin += (if (xCnt1 == 3) 1 else 0) + if (xCnt2 == 3) 1 else 0 return Pair(oWin, xWin) } fun solution(board: Array<String>): Int { val (oCounter, xCounter) = countMarker(board) if (oCounter - xCounter !in 0..1) return 0 val (oWin, xWin) = countWin(board) if ((oWin > 0 && xWin > 0) || (oWin > 0 && oCounter != xCounter + 1) || (xWin > 0 && oCounter != xCounter)) return 0 return 1 } }
class Solution { private fun countWin(board: Array<String>, marker: Char): Int { var win = board.map { row -> row.count { it == marker } }.count { it == 3 } win += (0..2).map { i -> ((0..2).map { j -> board[j][i] }) }.map { col -> col.count { it == marker } }.count { it == 3 } win += if ((0..2).count { board[it][it] == marker } == 3) 1 else 0 win += if ((0..2).count { board[it][2 - it] == marker } == 3) 1 else 0 return win } fun solution(board: Array<String>): Int { val countMarker = { array: Array<String>, marker: Char -> array.sumOf { row -> row.count { it == marker } } } val (oCounter, xCounter) = Pair(countMarker(board, 'O'), countMarker(board, 'X')) val (oWin, xWin) = Pair(countWin(board, 'O'), countWin(board, 'X')) return if ((oCounter - xCounter !in 0..1) || (oWin > 0 && xWin > 0) || (oWin > 0 && oCounter != xCounter + 1) || (xWin > 0 && oCounter != xCounter)) 0 else 1 } }
파이썬
리스트 컴프리헨션에서 이중포문을 쓰는 건 좋지 않다. (하지만 썼다.)
def count_win(board): win_o = win_x = 0 for i in range(3): row_o = row_x = col_o = col_x = 0 for j in range(3): if board[i][j] == 'O': row_o += 1 elif board[i][j] == 'X': row_x += 1 if board[j][i] == 'O': col_o += 1 elif board[j][i] == 'X': col_x += 1 win_o += (1 if row_o == 3 else 0) + (1 if col_o == 3 else 0) win_x += (1 if row_x == 3 else 0) + (1 if col_x == 3 else 0) cnt_o_1 = cnt_x_1 = cnt_o_2 = cnt_x_2 = 0 for i in range(3): cnt_o_1 += 1 if board[i][i] == 'O' else 0 cnt_x_1 += 1 if board[i][i] == 'X' else 0 cnt_o_2 += 1 if board[i][2 - i] == 'O' else 0 cnt_x_2 += 1 if board[i][2 - i] == 'X' else 0 win_o += (1 if cnt_o_1 == 3 else 0) + (1 if cnt_o_2 == 3 else 0) win_x += (1 if cnt_x_1 == 3 else 0) + (1 if cnt_x_2 == 3 else 0) return win_o, win_x def solution(board): count_o, count_x = tuple(map(sum, zip(*((each == 'O', each == 'X') for line in board for each in line)))) if count_o - count_x not in (0, 1): return 0 win_o, win_x = count_win(board) if (win_o > 0 and win_x > 0) or (win_o > 0 and count_o != count_x + 1) or (win_x > 0 and count_o != count_x): return 0 return 1
(O(n)을 고려하여) 한번에 'O'와 'X'를 처리하니 코드가 지저분하다. O(n)을 포기했다.
(과연 이래도 좋은가 애매하다. 읽기 좋은 코드가 선호되는 추세이긴 하다.)def count_win(board, marker): win = cnt1 = cnt2 = 0 for i in range(3): row = col = 0 for j in range(3): if board[i][j] == marker: row += 1 if board[j][i] == marker: col += 1 win += (1 if row == 3 else 0) + (1 if col == 3 else 0) for i in range(3): cnt1 += 1 if board[i][i] == marker else 0 cnt2 += 1 if board[i][2 - i] == marker else 0 win += (1 if cnt1 == 3 else 0) + (1 if cnt2 == 3 else 0) return win def solution(board): count_o, count_x = tuple(map(sum, zip(*((each == 'O', each == 'X') for line in board for each in line)))) win_o, win_x = count_win(board, 'O'), count_win(board, 'X') if count_o - count_x not in (0, 1) or (win_o > 0 and win_x > 0) \ or (win_o > 0 and count_o != count_x + 1) or (win_x > 0 and count_o != count_x): return 0 return 1
깔끔하게..
def count_win(board, marker): win = sum(all(each == marker for each in row) for row in board) win += sum(all(each == marker for each in col) for col in zip(*board)) win += all(board[i][i] == marker for i in range(3)) win += all(board[i][2 - i] == marker for i in range(3)) return win def solution(board): count_o, count_x = tuple(map(sum, zip(*((each == 'O', each == 'X') for line in board for each in line)))) win_o, win_x = count_win(board, 'O'), count_win(board, 'X') if count_o - count_x not in (0, 1) or (win_o > 0 and win_x > 0) \ or (win_o > 0 and count_o != count_x + 1) or (win_x > 0 and count_o != count_x): return 0 return 1
*board에 주의하자.
한 줄 더 줄여보자..
def count_win(board, marker): win = sum(all(each == marker for each in row) for row in board) win += sum(all(each == marker for each in col) for col in zip(*board)) win += sum(map(all, zip(*((board[i][i] == marker, board[i][2 - i] == marker) for i in range(3))))) return win def solution(board): count_o, count_x = tuple(map(sum, zip(*((each == 'O', each == 'X') for line in board for each in line)))) win_o, win_x = count_win(board, 'O'), count_win(board, 'X') if count_o - count_x not in (0, 1) or (win_o > 0 and win_x > 0) \ or (win_o > 0 and count_o != count_x + 1) or (win_x > 0 and count_o != count_x): return 0 return 1
그만하자.
반응형