Код Golf: Tic Tac Toe
Введите свой короткий код по количеству символов, чтобы проверить, выиграл ли игрок, и если да, то какой.
Предположим, что у вас есть целочисленный массив в переменной b
(доска), в которой находится плата Tic Tac Toe и движения игроков, где:
- 0 = ничего не установлено
- 1 = игрок 1 (X)
- 2 = игрок 2 (O)
Итак, если массив b = [ 1, 2, 1, 0, 1, 2, 1, 0, 2 ]
будет представлять плату
X|O|X
-+-+-
|X|O
-+-+-
X| |O
В этой ситуации ваш код должен выводить 1
, чтобы указать, что игрок 1 выиграл. Если никто не выиграл, вы можете вывести 0
или false
.
Мое собственное (Ruby) решение скоро появится.
Изменить: Извините, забыл отмечать его как вики сообщества. Вы можете предположить, что вход хорошо сформирован и не должен быть отмечен ошибкой.
Обновить: отправьте свое решение в виде функции. Большинство людей уже это сделали, но некоторые из них не имеют, что не совсем справедливо. Плата подается в вашу функцию в качестве параметра. Результат должен быть возвращен функцией. Функция может иметь имя по вашему выбору.
Ответы
Ответ 1
C, 77 (83) символов
Это вариант решения dmckee, за исключением того, что каждая пара цифр в Compact Coding теперь является базовыми цифрами ASCII-символов.
Версия 77 - char не работает в MSVC:
// "J)9\t8\r=,\0" == 82,45,63,10,62,14,67,48,00 in base 9.
char*k="J)9 8\r=,",c;f(int*b){return(c=*k++)?b[c/9]&b[c%9]&b[*k--%9]|f(b):0;}
Эта версия 83 - char должна работать на каждом компиляторе C:
f(int*b){char*k="J)9 8\r=,",s=0,c;while(c=*k++)s|=b[c%9]&b[c/9]&b[*k%9];return s;}
(Обратите внимание, что пробелы между 9 и 8 должны быть вкладкой. StackOverflow преобразует все вкладки в пробелы.)
Тестовый пример:
#include <stdio.h>
void check(int* b) {
int h0 = b[0]&b[1]&b[2];
int h1 = b[3]&b[4]&b[5];
int h2 = b[6]&b[7]&b[8];
int h3 = b[0]&b[3]&b[6];
int h4 = b[1]&b[4]&b[7];
int h5 = b[2]&b[5]&b[8];
int h6 = b[0]&b[4]&b[8];
int h7 = b[2]&b[4]&b[6];
int res = h0|h1|h2|h3|h4|h5|h6|h7;
int value = f(b);
if (value != res)
printf("Assuming f({%d,%d,%d, %d,%d,%d, %d,%d,%d}) == %d; got %d instead.\n",
b[0],b[1],b[2], b[3],b[4],b[5], b[6],b[7],b[8], res, value);
}
#define MAKEFOR(i) for(b[(i)]=0;b[(i)]<=2;++b[(i)])
int main() {
int b[9];
MAKEFOR(0)
MAKEFOR(1)
MAKEFOR(2)
MAKEFOR(3)
MAKEFOR(4)
MAKEFOR(5)
MAKEFOR(6)
MAKEFOR(7)
MAKEFOR(8)
check(b);
return 0;
}
Ответ 2
Решение Crazy Python - 79 символов
max([b[x] for x in range(9) for y in range(x) for z in range(y)
if x+y+z==12 and b[x]==b[y]==b[z]] + [0])
Однако это предполагает другой порядок для позиций платы в b:
5 | 0 | 7
---+---+---
6 | 4 | 2
---+---+---
1 | 8 | 3
То есть, b[5]
представляет верхний левый угол и т.д.
Чтобы свести к минимуму приведенное выше:
r=range
max([b[x]for x in r(9)for y in r(x)for z in r(y)if x+y+z==12and b[x]==b[y]==b[z]]+[0])
93 символа и новая строка.
Обновление: До 79 символов и новая строка с использованием побитового и трюка:
r=range
max([b[x]&b[y]&b[z]for x in r(9)for y in r(x)for z in r(y)if x+y+z==12])
Ответ 3
Python 80 (69) char
Не самое короткое решение Python, но мне нравится, как он вводит "DICE" в игру tic-tac-toc:
W=lambda b:max([b[c/5-9]&b[c/5+c%5-9]&b[c/5-c%5-9]for c in map(ord,"DICE>3BQ")])
69 символов для более простого выражения:
max([b[c/5-9]&b[c/5+c%5-9]&b[c/5-c%5-9]for c in map(ord,"DICE>3BQ")])
Ответ 4
Perl, 87 85 characters
Функция, которая возвращает 0, 1 или 2, используя регулярное выражение, конечно (новая строка только там, чтобы избежать полосы прокрутки):
sub V{$"='';$x='(1|2)';"@_"=~
/^(...)*$x\2\2|^..$x.\3.\3|$x..\4..\4|$x...\5...\5/?$^N:0}
Его можно назвать, например, V(@b)
.
Ответ 5
J, 50 символов
w=:3 : '{.>:I.+./"1*./"1]1 2=/y{~2 4 6,0 4 8,i,|:i=.i.3 3'
Ответ 6
Я не доволен повторением себя (горизонтальные/вертикальные и диагональные), но я думаю, что это честное начало.
С# w/LINQ:
public static int GetVictor(int[] b)
{
var r = Enumerable.Range(0, 3);
return r.Select(i => r.Aggregate(3, (s, j) => s & b[i * 3 + j])).Concat(
r.Select(i => r.Aggregate(3, (s, j) => s & b[j * 3 + i]))).Aggregate(
r.Aggregate(3, (s, i) => s & b[i * 3 + i]) | r.Aggregate(3, (s, i) => s & b[i * 3 + (2 - i)]),
(s, i) => s | i);
}
Стратегия: Побитовый AND
каждый элемент строки/столбца/диагональ с другими элементами (с 3 как семя), чтобы получить победителя для этого подмножества, и OR
все они вместе в конце.
Ответ 7
Ruby, 115 символов
К сожалению:. Как-то я много раз ошибался. Это на самом деле 115 символов, а не 79.
def t(b)[1,2].find{|p|[448,56,7,292,146,73,273,84].any?{|k|(k^b.inject(0){|m,i|m*2+((i==p)?1:0)})&k==0}}||false end
# Usage:
b = [ 1, 2, 1,
0, 1, 2,
1, 0, 2 ]
t(b) # => 1
b = [ 1, 1, 0,
2, 2, 2,
0, 2, 1 ]
t(b) # => 2
b = [ 0, 0, 1,
2, 2, 0,
0, 1, 1 ]
t(b) # => false
И расширенный код для образовательных целей:
def tic(board)
# all the winning board positions for a player as bitmasks
wins = [ 0b111_000_000, # 448
0b000_111_000, # 56
0b000_000_111, # 7
0b100_100_100, # 292
0b010_010_010, # 146
0b001_001_001, # 73
0b100_010_001, # 273
0b001_010_100 ] # 84
[1, 2].find do |player| # find the player who won
# for the winning player, one of the win positions will be true for :
wins.any? do |win|
# make a bitmask from the current player moves
moves = board.inject(0) { |acc, square|
# shift it to the left and add one if this square matches the player number
(acc * 2) + ((square == player) ? 1 : 0)
}
# some logic evaluates to 0 if the moves match the win mask
(win ^ moves) & win == 0
end
end || false # return false if the find returns nil (no winner)
end
Я уверен, что это может быть сокращено, особенно большой массив и, возможно, код для получения битовой маски игроков - эта тройная ошибка меня, но я думаю, что сейчас это очень хорошо.
Ответ 8
Perl, 76 char
sub W{$n=$u=0;map{$n++;$u|=$_[$_-$n]&$_[$_]&$_[$_+$n]for/./g}147,4,345,4;$u}
Существует три способа выигрыша по горизонтали:
0,1,2 ==> 1-1, 1, 1+1
3,4,5 ==> 4-1, 4, 4+1
6,7,8 ==> 7-1, 7, 7+1
Один из способов выиграть по диагонали от нижнего левого до верхнего правого:
2,4,6 ==> 4-2, 4, 4+2
Три способа выиграть по вертикали:
0,3,6 ==> 3-3, 3, 3+3
1,4,7 ==> 4-3, 4, 4+3
2,5,8 ==> 5-3, 5, 5+3
Один из способов выиграть по диагонали сверху слева вправо:
0,4,8 ==> 4-4, 4, 4+4
Прочитайте средние столбцы, чтобы получить магические числа.
Ответ 9
Octave/Matlab, 97 символов, включая пробелы и символы новой строки. Выходы 0, если нет победителя, 1, если игрок 1 выиграл, 2, если выиграл 2 игрока, и 2.0801, если оба игрока "выиграли":
function r=d(b)
a=reshape(b,3,3)
s=prod([diag(a) diag(fliplr(a)) a a'])
r=sum(s(s==1|s==8))^(1/3)
Если мы изменим спецификацию и перейдем в b как матрицу 3x3 с самого начала, мы можем удалить строку изменения, доведя ее до 80 символов.
Ответ 10
потому что никто не побеждает в tictactoe, когда правильно играл, я думаю, что это самый короткий код
echo 0;
7 символов
Обновление: лучшей записью для bash будет следующее:
86 символов или 81 исключая определение функции (win()).
win()for q in 1 28 55 3 12 21 4 20;{ [[ 3*w -eq B[f=q/8]+B[g=q%8]+B[g+g-f] ]]&&break;}
Но, это код из программы tic-tac-toe в bash, поэтому он не совсем соответствует спецификации.
# player is passed in caller w variable. I use O=0 and X=2 and empty=8 or 9
# if a winner is found, last result is true (and loop halts) else false
# since biggest test position is 7 I'll use base 8. could use 9 as well but 10 adds 2 characters to code length
# test cases are integers made from first 2 positions of each row
# eg. first row (0 1 2) is 0*8+1 = 1
# eg. diagonal (2 4 6) is 2*8+4 = 20
# to convert test cases to board positions use X/8, X%8, and X%8+(X%8-X/8)
# for each test case, test that sum of each tuplet is 3*player value
Ответ 11
Haskell, Предполагая магические квадраты выше. 77 Персонажи
77 исключает импорт и определяет b.
import Data.Bits
import Data.Array
b = listArray (0,8) [2,1,0,1,1,1,2,2,0]
w b = maximum[b!x.&.b!y.&.b!z|x<-[0..8],y<-[x+1..8],z<-[12-x-y],z<8,z>=0,z/=y]
Или 82, предполагая нормальный порядок:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.Bits
import Data.Array
b = listArray (0,8) [1,2,1,0,1,2,1,0,2]
w b = maximum[b!x.&.b!y.&.b!z|x<-[0..8],d<-[1..4],y<-[x+d],z<-[y+d],d/=2||x==2,z<9]
Ответ 12
(Iron) python, 75 символов
75 символов для полной функции
T=lambda a:max(a[b/6]&a[b/6+b%6]&a[b/6+b%6*2]for b in[1,3,4,9,14,15,19,37])
66 символов, если вы не укажете определение функции, как это делали другие,
r=max(a[b/6]&a[b/6+b%6]&a[b/6+b%6*2]for b in[1,3,4,9,14,15,19,37])
8 различных направлений представлены начальным значением + инкрементом, сжатым в одно число, которое может быть извлечено с использованием деления и модуляции. Например, 2,5,8 = 2 * 6 + 3 = 15.
Проверка того, что строка содержит три равных значения, выполняется с помощью оператора and. (что приводит к нулю, если они не равны). max используется для поиска возможного победителя.
Ответ 13
Ruby, 85 char
def X(b)
u=0
[2,6,7,8,9,13,21,-9].each do|c|u|=b[n=c/5+3]&b[n+c%5]&b[n-c%5]end
u
end
Если на входе выигрывают оба игрока, например
X | O | X
---+---+---
X | O | O
---+---+---
X | O | X
тогда выход равен 3.
Ответ 14
C, 99 символов
Не победитель, но, возможно, есть место для улучшения. Никогда раньше этого не делал. Оригинальная концепция, первый проект.
#define l w|=*b&b[s]&b[2*s];b+=3/s;s
f(int*b){int s=4,w=0;l=3;l;l;l=2;--b;l=1;b-=3;l;l;return l;}
Благодаря KennyTM для нескольких идей и тестового жгута.
"версия для разработки":
#define l w|=*b&b[s]&b[2*s];b+=3/s;s // check one possible win
f( int *b ) {
int s=4,w=0; // s = stride, w = winner
l=3; // check stride 4 and set to 3
l;l;l=2; // check stride 3, set to 2
--b;l=1; // check stride 2, set to 1
b-=3;l;l; return l; // check stride 1
}
Ответ 15
Решение в C (162 символа):
Это использует тот факт, что у игрока одно значение (1) и два игрока (2) имеют независимые биты. Следовательно, вы можете поразрядным образом и значения трех тестовых полей вместе - если значение отличное от нуля, то все три значения должны быть одинаковыми. Кроме того, полученное value == игрок, который выиграл.
Не самое короткое решение до сих пор, но лучшее, что я мог сделать:
void fn(){
int L[]={1,0,1,3,1,6,3,0,3,1,3,2,4,0,2,2,0};
int s,t,p,j,i=0;
while (s=L[i++]){
p=L[i++],t=3;
for(j=0;j<3;p+=s,j++)t&=b[p];
if(t)putc(t+'0',stdout);}
}
Более читаемая версия:
void fn2(void)
{
// Lines[] defines the 8 lines that must be tested
// The first value is the "Skip Count" for forming the line
// The second value is the starting position for the line
int Lines[] = { 1,0, 1,3, 1,6, 3,0, 3,1, 3,2, 4,0, 2,2, 0 };
int Skip, Test, Pos, j, i = 0;
while (Skip = Lines[i++])
{
Pos = Lines[i++]; // get starting position
Test = 3; // pre-set to 0x03 (player 1 & 2 values bitwise OR'd together)
// search each of the three boxes in this line
for (j = 0; j < 3; Pos+= Skip, j++)
{
// Bitwise AND the square with the previous value
// We make use of the fact that player 1 is 0x01 and 2 is 0x02
// Therefore, if any bits are set in the result, it must be all 1 or all 2's
Test &= b[Pos];
}
// All three squares same (and non-zero)?
if (Test)
putc(Test+'0',stdout);
}
}
Ответ 16
Python, 102 символа
Поскольку вы не указали, как получить ввод и вывод, это "сырая" версия, которая, возможно, должна быть включена в функцию. b
- список ввода; r
- выход (0, 1 или 2).
r=0
for a,c in zip("03601202","11133342"):s=set(b[int(a):9:int(c)][:3]);q=s.pop();r=r if s or r else q
Ответ 17
Lua, 130 символов
130 символов - это только размер функции. Функция не возвращает ничего, если совпадение не найдено, что в Lua аналогично возврату false.
function f(t)z={7,1,4,1,1,3,2,3,3}for b=1,#z-1 do
i=z[b]x=t[i]n=z[b+1]if 0<x and x==t[i+n]and x==t[i+n+n]then
return x end end end
assert(f{1,2,1,0,1,2,1,0,2}==1)
assert(f{1,2,1,0,0,2,1,0,2}==nil)
assert(f{1,1,2,0,1,2,1,0,2}==2)
assert(f{2,1,2,1,2,1,2,1,2}==2)
assert(f{2,1,2,1,0,2,2,2,1}==nil)
assert(f{1,2,0,1,2,0,1,2,0}~=nil)
assert(f{0,2,0,0,2,0,0,2,0}==2)
assert(f{0,2,2,0,0,0,0,2,0}==nil)
assert(f{0,0,0,0,0,0,0,0,0}==nil)
assert(f{1,1,1,0,0,0,0,0,0}==1)
assert(f{0,0,0,1,1,1,0,0,0}==1)
assert(f{0,0,0,0,0,0,1,1,1}==1)
assert(f{1,0,0,1,0,0,1,0,0}==1)
assert(f{0,1,0,0,1,0,0,1,0}==1)
assert(f{0,0,1,0,0,1,0,0,1}==1)
assert(f{1,0,0,0,1,0,0,0,1}==1)
assert(f{0,0,1,0,1,0,1,0,0}==1)
Ответ 18
Visual Basic 275 254 (с непринужденной типизацией)
Function W(ByVal b())
Dim r
For p = 1 To 2
If b(0) = b(1) = b(2) = p Then r = p
If b(3) = b(4) = b(5) = p Then r = p
If b(6) = b(7) = b(8) = p Then r = p
If b(0) = b(3) = b(6) = p Then r = p
If b(1) = b(4) = b(7) = p Then r = p
If b(2) = b(5) = b(8) = p Then r = p
If b(0) = b(4) = b(8) = p Then r = p
If b(6) = b(4) = b(2) = p Then r = p
Next
Return r
End Function
Ответ 19
JavaScript - функция "w" ниже - 114 символов
<html>
<body>
<script type="text/javascript">
var t = [0,0,2,0,2,0,2,0,0];
function w(b){
i = '012345678036147258048642';
for (l=0;l<=21;l+=3){
v = b[i[l]];
if (v == b[i[l+1]]) if (v == b[i[l+2]]) return v;
}
}
alert(w(t));
</script>
</body>
</html>
Ответ 20
J, 97 символов.
1+1 i.~,+./"2>>(0 4 8,2 4 6,(],|:)3 3$i.9)&(e.~)&.>&.>(]<@:#"1~[:#:[:i.2^#)&.>([email protected](1&=);[email protected](2&=))
Я планировал опубликовать объяснение, как это работает, но это было вчера, и теперь я не могу прочитать этот код.
Идея заключается в том, что мы создаем список всех возможных выигрышных троек (048,246,012,345,678,036,147,258), затем создаем набор квадратов каждого игрока, а затем пересекаем два списка. Если есть совпадение, то победитель.
Ответ 21
Python - 75 символов (64)
Я придумал 2 выражения, каждые 64chars:
max(a[c/8]&a[c/8+c%8]&a[c/8-c%8]for c in map(ord,'\t\33$#"!+9'))
и
max(a[c/5]&a[c/5+c%5]&a[c/5+c%5*2]for c in[1,3,4,8,12,13,16,31])
Когда вы добавляете "W = лямбда b:", чтобы сделать его функцией, это делает 75chars.
Самый короткий Python до сих пор?
Ответ 22
Python, 285 байт
b,p,q,r=["."]*9,"1","2",range
while"."in b:
w=[b[i*3:i*3+3]for i in r(3)]+[b[i::3]for i in r(3)]+[b[::4],b[2:8:2]]
for i in w[:3]:print i
if["o"]*3 in w or["x"]*3 in w:exit(q)
while 1:
m=map(lambda x:x%3-x+x%3+7,r(9)).index(input())
if"."==b[m]:b[m]=".xo"[int(p)];p,q=q,p;break
... О, это было не то, что вы имели в виду, когда вы сказали "Code Golf: Tic Tac Toe"?;) (введите цифры numpad для размещения x или o, т.е. 7 - северо-запад)
Длинная версия
board = ["."]*9 # the board
currentname = "1" # the current player
othername = "2" # the other player
numpad_dict = {7:0, 8:1, 9:2, # the lambda function really does this!
4:3, 5:4, 6:5,
1:6, 2:7, 3:8}
while "." in board:
# Create an array of possible wins: horizontal, vertical, diagonal
wins = [board[i*3:i*3+3] for i in range(3)] + \ # horizontal
[board[i::3] for i in range(3)] + \ # vertical
[board[::4], board[2:8:2]] # diagonal
for i in wins[:3]: # wins contains the horizontals first,
print i # so we use it to print the current board
if ["o"]*3 in wins or ["x"]*3 in wins: # somebody won!
exit(othername) # print the name of the winner
# (we changed player), and exit
while True: # wait for the player to make a valid move
position = numpad_dict[input()]
if board[position] == ".": # still empty -> change board
if currentname == "1":
board[position] = "x"
else:
board[position] = "o"
currentname, othername = othername, currentname # swap values
Ответ 23
Я уверен, что есть более короткий способ сделать это, но... Perl, 141 символ (134 внутри функции)
sub t{$r=0;@[email protected]_;@w=map{[split//]}split/,/,"012,345,678,036,147,258,048,246";for(@w){@z=map{$b[$_]}@$_;$r=$z[0]if!grep{!$_||$_!=$z[0]}@z;}$r;}
Ответ 24
Ruby, 149 символов
def s(b)(0..8).to_a+[0,3,6,1,4,7,2,5,8,0,4,8,2,4,6].each_slice(3){|m|if b.values_at(*m).uniq.length<2&&b[m[0]]!=0;return b[m[0]];end}return false;end
Это разумное решение, я уверен, что смогу его еще немного уменьшить. Вот читаемая версия:
def someone_won(b)
helper = (0..8).to_a + [ 0, 3, 6, 1, 4, 7, 2, 5, 8, 0, 4, 8, 2, 4, 6]
helper.each_slice(3) { |m|
if b.values_at(*m).uniq.length < 2 && b[m[0]] != 0
return b[m[0]]
end
}
return false
end
Ответ 25
С#, 154 163 170 177 символы
Заимствование нескольких методов из других материалов.
(не знал, С# позволяет инициализировать массивы, подобные этому)
static int V(int[] b)
{
int[] a={0,1,3,1,6,1,0,3,1,3,2,3,0,4,2,2};
int r=0,i=-2;
while((i+=2)<16&&(r|=b[a[i]]&b[a[i]+a[i+1]]&b[a[i]+a[i+1]*2])==0){}
return r;
}
Ответ 26
c - 144 символа
уменьшенная:
#define A(x) a[b[x%16]]
int c,b[]={4,8,0,1,2,4,6,0,3,4,5,2,8,6,7,2};int
T(int*a){for(c=0;c<16;c+=2)if(A(c)&A(c+1)&A(c+2))return A(c);return 0;}
Оба возвращают счетчик (один необходимый, а другой нужно заменить пробелом).
Коды массивов для восьми способов выиграть в тройках, начиная с четных позиций и взятых по модулю 16.
Побитовое и трюковое украденное из Эрика Пи.
Более читаемая форма:
#define A(x) a[b[x%16]]
// Compact coding of the ways to win.
//
// Each possible was starts a position N*2 and runs through N*2+2 all
// taken mod 16
int c,b[]={4,8,0,1,2,4,6,0,3,4,5,2,8,6,7,2};
int T(int*a){
// Loop over the ways to win
for(c=0;c<16;c+=2)
// Test for a win
if(A(c)&A(c+1)&A(c+2))return A(c);
return 0;
}
Испытательный эшафот:
#include <stdlib.h>
#include <stdio.h>
int T(int*);
int main(int argc, char**argv){
int input[9]={0};
int i, j;
for (i=1; i<argc; ++i){
input[i-1] = atoi(argv[i]);
};
for (i=0;i<3;++i){
printf("%1i %1i %1i\n",input[3*i+0],input[3*i+1],input[3*i+2]);
};
if (i = T(input)){
printf("%c wins!\n",(i==1)?'X':'O');
} else {
printf("No winner.\n");
}
return 0;
}
Ответ 27
Вероятно, может быть сделано лучше, но сейчас я не чувствую себя особенно умным. Это просто, чтобы убедиться, что Haskell представлен...
Предполагая, что b
уже существует, это приведет к результату в w
.
import List
a l=2*minimum l-maximum l
z=take 3$unfoldr(Just .splitAt 3)b
w=maximum$0:map a(z++transpose z++[map(b!!)[0,4,8],map(b!!)[2,4,6]])
Предполагая ввод из stdin и вывода в stdout,
import List
a l=2*minimum l-maximum l
w b=maximum$0:map a(z++transpose z++[map(b!!)[0,4,8],map(b!!)[2,4,6]])where
z=take 3$unfoldr(Just .splitAt 3)b
main=interact$show.w.read
Ответ 28
С#, 180 символов:
var s=new[]{0,0,0,1,2,2,3,6};
var t=new[]{1,3,4,3,2,3,1,1};
return(s.Select((p,i)=>new[]{g[p],g[p+t[i]],g[p+2*t[i]]}).FirstOrDefault(l=>l.Distinct().Count()==1)??new[]{0}).First();
(g
является сеткой)
Возможно, будет улучшено... Я все еще работаю над этим;)
Ответ 29
Python, 140 символов
Мой первый гольф-код, взвешиваемый на здоровенных 140 символах (выражение об импорте, я отрицаю вас!):
import operator as o
def c(t):return({1:1,8:2}.get(reduce(o.mul,t[:3]),0))
def g(t):return max([c(t[x::y]) for x,y in zip((0,0,0,1,2,2,3,6),(1,3,4,3,3,2,1,1))])
Чуть менее неясное g:
def g(t):return max([c(t[x::y]) for x,y in [[0,1],[0,3],[0,4],[1,3],[2,3],[2,2],[3,1],[6,1]]])
Ответ 30
Решение С#.
Умножьте значения в каждой строке, col и диагонали. Если результат == 1, побеждает X. Если результат == 8, побеждает О.
int v(int[] b)
{
var i = new[] { new[]{0,1,2}, new[]{3,4,5}, new[]{6,7,8}, new[]{0,3,6}, new[]{1,4,7}, new[]{2,5,8}, new[]{0,4,8}, new[]{2,4,6} };
foreach(var a in i)
{
var n = b[a[0]] * b[a[1]] * b[a[2]];
if(n==1) return 1;
if(n==8) return 2;
}
return 0;
}