Dashboard - Qualification Round 2013 - Google Code Jam
Tic-Tac-Toe-Tomek is a game played on a 4 x 4 square board. The board starts empty, except that a single 'T' symbol may appear in one of the 16 squares. There are two players: X and O. They take turns to make moves, with X starting. In each move a player puts her symbol in one of the empty squares. Player X's symbol is 'X', and player O's symbol is 'O'.
After a player's move, if there is a row, column or a diagonal containing 4 of that player's symbols, or containing 3 of her symbols and the 'T' symbol, she wins and the game ends. Otherwise the game continues with the other player's move. If all of the fields are filled with symbols and nobody won, the game ends in a draw. See the sample input for examples of various winning positions.
Given a 4 x 4 board description containing 'X', 'O', 'T' and '.' characters (where '.' represents an empty square), describing the current state of a game, determine the status of the Tic-Tac-Toe-Tomek game going on. The statuses to choose from are:
http://united-coders.com/christian-harms/google-code-jam-2013-tic-tac-toe-tomek-solution/
https://code.google.com/codejam/contest/2270488/dashboard#s=a&a=0
http://toughprogramming.blogspot.com/2013/04/code-jam-2013-qualification-round.html
Use int score.
Read full article from Dashboard - Qualification Round 2013 - Google Code Jam
Tic-Tac-Toe-Tomek is a game played on a 4 x 4 square board. The board starts empty, except that a single 'T' symbol may appear in one of the 16 squares. There are two players: X and O. They take turns to make moves, with X starting. In each move a player puts her symbol in one of the empty squares. Player X's symbol is 'X', and player O's symbol is 'O'.
After a player's move, if there is a row, column or a diagonal containing 4 of that player's symbols, or containing 3 of her symbols and the 'T' symbol, she wins and the game ends. Otherwise the game continues with the other player's move. If all of the fields are filled with symbols and nobody won, the game ends in a draw. See the sample input for examples of various winning positions.
Given a 4 x 4 board description containing 'X', 'O', 'T' and '.' characters (where '.' represents an empty square), describing the current state of a game, determine the status of the Tic-Tac-Toe-Tomek game going on. The statuses to choose from are:
- "X won" (the game is over, and X won)
- "O won" (the game is over, and O won)
- "Draw" (the game is over, and it ended in a draw)
- "Game has not completed" (the game is not over yet)
http://united-coders.com/christian-harms/google-code-jam-2013-tic-tac-toe-tomek-solution/
X. solution with bit masks
The game field has 16 items with 4 states [“.”, “O”, “X”, “T”]. This can be converted into a 32 bit value. And if you choose “O”:1 and “X”:2 then will result “T”:3 with an AND-operation for both in a TRUE!
def solve_with_bits(lines): mapping = {".":0, "O": 1, "X":2, "T":3} m = 0 #convert input lines in 32-bit-number! for c in lines: if mapping.has_key(c): m = (m<<2)+mapping[c] pat = [(4, 0x55, 1, 7), # 4x, horicontal, 1 bit for O, 8 bit next test (4, 0x01010101, 1, 1), # 4x, vert. line, next Vert. only 1 bit (1, 0x01041040, 1, 1), # 1x, /, 1 bit shift (1, 0x40100401, 1, 1) # 1x, \, 1 bit shift ] #check win situation for O and X for loop, hBits, shift1, shift2 in pat: for i in range(loop): if m & hBits == hBits: return "O won" hBits = hBits << shift1 # 1 bit shift for X if m & hBits == hBits: return "X won" hBits = hBits << shift2 if lines.find(".")!=-1: return "Game has not completed" return "Draw"X. Using Regular Expression.
This kind of problem can be easy solved with a regex if you use the field in one string:
lines = “XOOX\nOXXO\nOOTX\nOOOX”
import re, sys pattern = "OOOO|O....O....O....O|O.....O.....O.....O|O...O...O...O" checkO = re.compile(pattern, re.S) checkX = re.compile(pattern.replace("O","X"), re.S) def solve_with_regex(lines): #set T to O and test with the O-regex if checkO.search(lines.replace("T", "O")): return "O won" #set T to X and test with the X-regex if checkX.search(lines.replace("T", "X")): return "X won" if lines.find(".")!=-1: return "Game has not completed" return "Draw" #solved IN = file(sys.argv[1]) for t in range(1, int(IN.readline())+1): lines = "".join([IN.readline() for x in range(5)]) print "Case #%d: %s" % (t, solve_with_regex(lines))Official Analysis
https://code.google.com/codejam/contest/2270488/dashboard#s=a&a=0
def solve(b): for c in ['X', 'O']: wind1 = True wind2 = True for x in range(4): winh = True winv = True for y in range(4): if b[y][x]!=c and b[y][x]!='T': winv = False if b[x][y]!=c and b[x][y]!='T': winh = False if winh or winv: return c + ' won' if b[x][x]!=c and b[x][x]!='T': wind1 = False if b[3-x][x]!=c and b[3-x][x]!='T': wind2 = False if wind1 or wind2: return c + ' won' for x in range(4): for y in range(4): if b[y][x]=='.': return 'Game has not completed' return 'Draw'https://gist.github.com/KuoE0/5381830
bool checkFull( char board[][ 10 ] ) { | |
for ( int i = 0; i < 4; ++i ) | |
for ( int j = 0; j < 4; ++j ) | |
if ( board[ i ][ j ] == '.' ) | |
return false; | |
return true; | |
} | |
bool checkRowCol( char board[][ 10 ], char k, int rc, bool dir ) { | |
int cnt = 0, T = 0; | |
for ( int i = 0; i < 4; ++i ) { | |
char c = board[ dir ? i : rc ][ dir ? rc : i ]; | |
cnt += c == k ? 1 : 0; | |
T += c == 'T' ? 1 : 0; | |
} | |
return cnt == 4 || ( cnt == 3 && T == 1 ); | |
} | |
bool checkDiagonal( char board[][ 10 ], char k, bool dir ) { | |
int cnt = 0, T = 0; | |
for ( int i = 0; i < 4; ++i ) { | |
int c = board[ i ][ dir ? 3 - i : i ]; | |
cnt += c == k ? 1 : 0; | |
T += c == 'T' ? 1 : 0; | |
} | |
return cnt == 4 || ( cnt == 3 && T == 1 ); | |
} | |
bool checkWin( char board[][ 10 ], char k ) { | |
for ( int i = 0; i < 4; ++i ) | |
if ( checkRowCol( board, k, i, 0 ) || checkRowCol( board, k, i, 1 ) ) | |
return true; | |
for ( int i = 0; i < 2; ++i ) | |
if ( checkDiagonal( board, k, i ) ) | |
return true; | |
return false; | |
} | |
if ( checkWin( board, 'X' ) ) printf( "Case #%d: X won\n", test + 1 ); | |
else if ( checkWin( board, 'O' ) ) | |
printf( "Case #%d: O won\n", test + 1 ); | |
else if ( !checkFull( board ) ) | |
printf( "Case #%d: Game has not completed\n", test + 1 ); | |
else | |
printf( "Case #%d: Draw\n", test + 1 ); |
Use int score.
private static void checkScore(char[][] board, int caseNum,
boolean notComplete) throws IOException {
// TODO Auto-generated method stub
// check diagonals first
// first diagonal
int j = 0;
int xcount = 1;
int ycount = 1;
boolean tFound = false;
for (int i = 0; i < 4; ++i) {
if (board[i][j] == 'T') {
++xcount;
++ycount;
} else if (board[i][j] == 'X') {
++xcount;
} else if (board[i][j] == 'O') {
++ycount;
}
++j;
}
if (xcount == 5) {
writer.write("Case #" + (caseNum + 1) + ": X won");
writer.newLine();
return;
}
if (ycount == 5) {
writer.write("Case #" + (caseNum + 1) + ": O won");
writer.newLine();
return;
}
// ///////////////////////////////////////////////////////////////////////
// second diagonal
j = 3;
xcount = 1;
ycount = 1;
tFound = false;
for (int i = 0; i < 4; ++i) {
if (board[i][j] == 'T') {
++xcount;
++ycount;
} else if (board[i][j] == 'X') {
++xcount;
} else if (board[i][j] == 'O') {
++ycount;
}
--j;
}
if (xcount == 5) {
writer.write("Case #" + (caseNum + 1) + ": X won");
writer.newLine();
return;
}
if (ycount == 5) {
writer.write("Case #" + (caseNum + 1) + ": O won");
writer.newLine();
return;
}
// ////////////////////////////////////////////////////////////////////////
// checking rows and cols
for (int i = 0; i < 4; ++i) {
xcount = 1;
ycount = 1;
tFound = false;
for (int row = 0; row < 4; ++row) {
if (board[row][i] == 'T') {
++xcount;
++ycount;
} else if (board[row][i] == 'X') {
++xcount;
} else if (board[row][i] == 'O') {
++ycount;
}
}
if (xcount == 5) {
writer.write("Case #" + (caseNum + 1) + ": X won");
writer.newLine();
return;
}
if (ycount == 5) {
writer.write("Case #" + (caseNum + 1) + ": O won");
writer.newLine();
return;
}
xcount = 1;
ycount = 1;
tFound = false;
for (int col = 0; col < 4; ++col) {
if (board[i][col] == 'T') {
++xcount;
++ycount;
} else if (board[i][col] == 'X') {
++xcount;
} else if (board[i][col] == 'O') {
++ycount;
}
}
if (xcount == 5) {
writer.write("Case #" + (caseNum + 1) + ": X won");
writer.newLine();
return;
}
if (ycount == 5) {
writer.write("Case #" + (caseNum + 1) + ": O won");
writer.newLine();
return;
}
}
if (notComplete) {
writer.write("Case #" + (caseNum + 1) + ": Game has not completed");
writer.newLine();
return;
}
writer.write("Case #" + (caseNum + 1) + ": Draw");
writer.newLine();
return;
}
http://arxoclay.blogspot.com/2013/04/google-code-jam-tic-tac-toe-tomek.html
def hasWon(boardState, winningSymbol):
# Horizontal Check
for row in range(len(boardState)):
rowWinner = True
for column in range(len(boardState)):
if boardState[row][column] == winningSymbol or boardState[row][column] == "T":
continue
else:
rowWinner = False
break
if rowWinner == True:
return True
# Vertical Check
for column in range(len(boardState)):
columnWinner = True
for row in range(len(boardState)):
if boardState[row][column] == winningSymbol or boardState[row][column] == "T":
continue
else:
columnWinner = False
break
if columnWinner == True:
return True
# Diagonal Check
if (boardState[0][0] == winningSymbol or boardState[0][0] == "T") and(boardState[1][1] == winningSymbol or boardState[1][1] == "T") and(boardState[2][2] == winningSymbol or boardState[2][2] == "T") and(boardState[3][3] == winningSymbol or boardState[3][3] == "T"):
return True
if (boardState[0][3] == winningSymbol or boardState[0][3] == "T") and(boardState[1][2] == winningSymbol or boardState[1][2] == "T") and(boardState[2][1] == winningSymbol or boardState[2][1] == "T") and(boardState[3][0] == winningSymbol or boardState[3][0] == "T"):
return True
def hasEmptySpaces(boardState):
for row in range(len(boardState)):
for column in range(len(boardState)):
if boardState[row][column] == ".":
return True
return False
def ticTacToeTomek(boardState):
if hasWon(boardState, "X"):
return "X won"
elif hasWon(boardState, "O"):
return "O won"
elif hasEmptySpaces(boardState):
return "Game has not completed"
return "Draw"
Read full article from Dashboard - Qualification Round 2013 - Google Code Jam