forked from yennanliu/CS_basics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind-winner-on-a-tic-tac-toe-game.py
150 lines (110 loc) · 5.18 KB
/
find-winner-on-a-tic-tac-toe-game.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"""
1275. Find Winner on a Tic Tac Toe Game
Easy
Tic-tac-toe is played by two players A and B on a 3 x 3 grid. The rules of Tic-Tac-Toe are:
Players take turns placing characters into empty squares ' '.
The first player A always places 'X' characters, while the second player B always places 'O' characters.
'X' and 'O' characters are always placed into empty squares, never on filled ones.
The game ends when there are three of the same (non-empty) character filling any row, column, or diagonal.
The game also ends if all squares are non-empty.
No more moves can be played if the game is over.
Given a 2D integer array moves where moves[i] = [rowi, coli] indicates that the ith move will be played on grid[rowi][coli]. return the winner of the game if it exists (A or B). In case the game ends in a draw return "Draw". If there are still movements to play return "Pending".
You can assume that moves is valid (i.e., it follows the rules of Tic-Tac-Toe), the grid is initially empty, and A will play first.
Example 1:
Input: moves = [[0,0],[2,0],[1,1],[2,1],[2,2]]
Output: "A"
Explanation: A wins, they always play first.
Example 2:
Input: moves = [[0,0],[1,1],[0,1],[0,2],[1,0],[2,0]]
Output: "B"
Explanation: B wins.
Example 3:
Input: moves = [[0,0],[1,1],[2,0],[1,0],[1,2],[2,1],[0,1],[0,2],[2,2]]
Output: "Draw"
Explanation: The game ends in a draw since there are no moves to make.
Constraints:
1 <= moves.length <= 9
moves[i].length == 2
0 <= rowi, coli <= 2
There are no repeated elements on moves.
moves follow the rules of tic tac toe.
"""
# V0
# V1
# IDEA : BRUTE FORCE
# https://leetcode.com/problems/find-winner-on-a-tic-tac-toe-game/solution/
class Solution:
def tictactoe(self, moves: List[List[int]]) -> str:
# Initialize the board, n = 3 in this problem.
n = 3
board = [[0] * n for _ in range(n)]
# Check if any of 4 winning conditions to see if the current player has won.
def checkRow(row, player_id):
for col in range(n):
if board[row][col] != player_id:
return False
return True
def checkCol(col, player_id):
for row in range(n):
if board[row][col] != player_id:
return False
return True
def checkDiagonal(player_id):
for row in range(n):
if board[row][row] != player_id:
return False
return True
def checkAntiDiagonal(player_id):
for row in range(n):
if board[row][n - 1 - row] != player_id:
return False
return True
# Start with player_1.
player = 1
for move in moves:
row, col = move
board[row][col] = player
# If any of the winning conditions is met, return the current player's id.
if checkRow(row, player) or checkCol(col, player) or \
(row == col and checkDiagonal(player)) or \
(row + col == n - 1 and checkAntiDiagonal(player)):
return 'A' if player == 1 else 'B'
# If no one wins so far, change to the other player alternatively.
# That is from 1 to -1, from -1 to 1.
player *= -1
# If all moves are completed and there is still no result, we shall check if
# the grid is full or not. If so, the game ends with draw, otherwise pending.
return "Draw" if len(moves) == n * n else "Pending"
# V1'
# IDEA : RECORD EACH MOVE
# https://leetcode.com/problems/find-winner-on-a-tic-tac-toe-game/solution/
class Solution:
def tictactoe(self, moves: List[List[int]]) -> str:
# n stands for the size of the board, n = 3 for the current game.
n = 3
# use rows and cols to record the value on each row and each column.
# diag1 and diag2 to record value on diagonal or anti-diagonal.
rows, cols = [0] * n, [0] * n
diag = anti_diag = 0
# Two players having value of 1 and -1, player_1 with value = 1 places first.
player = 1
for row, col in moves:
# Update the row value and column value.
rows[row] += player
cols[col] += player
# If this move is placed on diagonal or anti-diagonal,
# we shall update the relative value as well.
if row == col:
diag += player
if row + col == n - 1:
anti_diag += player
# check if this move meets any of the winning conditions.
if any(abs(line) == n for line in (rows[row], cols[col], diag, anti_diag)):
return "A" if player == 1 else "B"
# If no one wins so far, change to the other player alternatively.
# That is from 1 to -1, from -1 to 1.
player *= -1
# If all moves are completed and there is still no result, we shall check if
# the grid is full or not. If so, the game ends with draw, otherwise pending.
return "Draw" if len(moves) == n * n else "Pending"
# V2