Гольф кода: тик палец ноги Tac

Отправьте свой самый короткий код счетчиком символов, чтобы проверить, победил ли игрок, и если так, который.

Предположите, что у Вас есть целочисленный массив в переменной b (плата), которая содержит Тик плата Пальца ноги Tac и перемещения плееров где:

  • 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) решение скоро произойдет.

Править: Извините, забыл отмечать его как общественную Wiki. Можно предположить, что вход хорошо формируется и не должен быть проверенной ошибкой.


Обновление: отправьте свое решение в форме функции. Большинство людей уже сделало это, но некоторые не имеют, который не совершенно справедлив. Плата предоставляется Вашей функции как параметр. Результат должен быть возвращен функцией. Функция может иметь название Вашего выбора.

42
задан 4 revs, 2 users 100% 14 March 2010 в 04:50
поделиться

35 ответов

C, 77 (83) символов

Это вариант решения dmckee , за исключением того, что каждая пара цифр в компактном кодировании теперь является цифрами с основанием 9 символов 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;
}
22
ответ дан 26 November 2019 в 23:20
поделиться

Я уверен, что есть более короткий способ сделать это, но ... Perl, 141 символ (134 внутри функции)

sub t{$r=0;@b=@_;@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;}
0
ответ дан 26 November 2019 в 23:20
поделиться

Решение на C#.

Перемножьте значения в каждой строке, столбце и диагонали. Если результат == 1, побеждает X. Если результат == 8, побеждает O.

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;
}
0
ответ дан 26 November 2019 в 23:20
поделиться

C #, 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 - сетка)

Возможно, можно улучшить ... Я ' m все еще работает над этим;)

0
ответ дан 26 November 2019 в 23:20
поделиться

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]]])
0
ответ дан 26 November 2019 в 23:20
поделиться

Наверное, можно было бы улучшить, но сейчас я не чувствую себя особенно умным. Это просто для того, чтобы убедиться, что 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]])

Предполагая, что ввод из стандартного ввода и вывод в стандартный вывод,

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
0
ответ дан 26 November 2019 в 23:20
поделиться

C, 113 символов

f(int*b){char*s="012345678036147258048264\0";int r=0;while(!r&&*s){int q=r=3;while(q--)r&=b[*s++-'0'];}return r;}

Думаю, это работает? Мой первый код гольф, будь нежным.

Каждые 3 цифры кодируют 3 ячейки, которые необходимо сопоставить. Внутренний пока проверяет триаду. Внешний while проверяет все 8.

0
ответ дан 26 November 2019 в 23:20
поделиться

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>
1
ответ дан 26 November 2019 в 23:20
поделиться

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 символов.

4
ответ дан 26 November 2019 в 23:20
поделиться

Perl, 87 85 символов

Функция, которая возвращает 0, 1 или 2, конечно, с использованием регулярного выражения (новая строка присутствует только во избежание полосы прокрутки):

sub V{$"='';$x='(1|2)';"@_"=~
/^(...)*$x\2\2|^..$x.\3.\3|$x..\4..\4|$x...\5...\5/?$^N:0}

Она может называться, например, V (@b) .

10
ответ дан 26 November 2019 в 23:20
поделиться

Мне не нравится повторяться (по горизонтали / вертикали и по диагонали), но я думаю, что это хорошее начало.

C # с 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);
}

Стратегия: побитовое И каждый элемент строки / столбца / диагонали с другими элементами (с 3 в качестве начального числа), чтобы получить победителя для этого подмножества, и ИЛИ их все вместе в конце.

9
ответ дан 26 November 2019 в 23:20
поделиться

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's 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's 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
ответ дан 26 November 2019 в 23:20
поделиться

Python 80 (69) char

Не самое короткое решение на Python, но мне нравится, как оно вводит "DICE" в игру в крестики-нолики:

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 chars для более простого выражения:

max([b[c/5-9]&b[c/5+c%5-9]&b[c/5-c%5-9]for c in map(ord,"DICE>3BQ")])
12
ответ дан 26 November 2019 в 23:20
поделиться

Perl, 76 символов

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

Прочтите средние столбцы, чтобы получить магические числа.

4
ответ дан 26 November 2019 в 23:20
поделиться

(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.

Проверка того, что строка содержит три равных значения, выполняется с помощью оператора &. (что дает ноль, если они не равны). max используется для поиска возможного победителя.

2
ответ дан 26 November 2019 в 23:20
поделиться

Решение на C (162 символа):

Здесь используется тот факт, что значение игрока один (1) и значение игрока два (2) имеют независимый набор битов. Поэтому можно выполнить побитовое AND значений трех тестовых полей вместе - если значение ненулевое, то все три значения должны быть одинаковыми. Кроме того, полученное значение == игрок, который выиграл.

Не самое короткое решение, но лучшее, что я смог сделать:

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's or all 2's
            Test &= b[Pos];
        }

        // All three squares same (and non-zero)?
        if (Test)
            putc(Test+'0',stdout);
    }
}
1
ответ дан 26 November 2019 в 23:20
поделиться

Вы рассматривали возможность использования базы данных для хранения конфигурации приложения? В Apache Commons имеется класс, который представляет таблицу как экземпляр java.util.Properties (см. http://commons.apache.org/configuration/apidocs/org/apache/commons/configuration/DatabaseConfiguration.html ).

-121--4518533-
  1. Да. Когда вы преобразуете значения, вам не нужно беспокоиться об эндианнесе.

  2. Да. При преобразовании указателей происходит.

-121--3594900-

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
1
ответ дан 26 November 2019 в 23:20
поделиться

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)
1
ответ дан 26 November 2019 в 23:20
поделиться

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.

2
ответ дан 26 November 2019 в 23:20
поделиться

Безумное решение 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])
37
ответ дан 26 November 2019 в 23:20
поделиться

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
1
ответ дан 26 November 2019 в 23:20
поделиться

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;}

Спасибо Kenny TM за несколько идей и испытательный комплект.

«Версия для разработки»:

#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
}
2
ответ дан 26 November 2019 в 23:20
поделиться

J, 50 символов

w=:3 : '{.>:I.+./"1*./"1]1 2=/y{~2 4 6,0 4 8,i,|:i=.i.3 3'
10
ответ дан 26 November 2019 в 23:20
поделиться

потому что никто не выигрывает в 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;}

Но это код программы крестики-нолики в bash, поэтому он не совсем соответствует спецификации.

# player is passed in caller's 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
3
ответ дан 26 November 2019 в 23:20
поделиться

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;}

Оба возврата считаются (один необходим, а другой нужно заменить пробелом).

Коды массивов для восьми способов выиграть в триплетах, начиная с четных позиций и взятых mod 16.

Побитовые коды и трюк украдены у Eric Pi.


Более читабельная форма:

#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;
}
0
ответ дан 26 November 2019 в 23:20
поделиться

Хаскелл, принимая магические квадраты выше. 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]
2
ответ дан 26 November 2019 в 23:20
поделиться

C#, 154 163 170 177 символов

Заимствуя пару приемов из других представлений. (не знал, что C# позволяет так инициализировать массивы)

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;
}
0
ответ дан 26 November 2019 в 23:20
поделиться

J, 97 символов.

1+1 i.~,+./"2>>(0 4 8,2 4 6,(],|:)3 3$i.9)&(e.~)&.>&.>(]<@:#"1~[:#:[:i.2^#)&.>(I.@(1&=);I.@(2&=))

Я планировал опубликовать объяснение того, как это работает, но это было вчера, и теперь я не могу прочитать этот код.

Идея состоит в том, чтобы создать список всех возможных выигрышных троек (048 246 012 345 678 036 147 258), затем составить набор квадратов, имеющихся у каждого игрока, и затем пересечь два списка. Если есть совпадение, это победитель.

1
ответ дан 26 November 2019 в 23:20
поделиться

Python - 75 символов (64)

Я придумал 2 выражения, каждое по 64 символа:

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 = lambda b:», чтобы получилось функция, которая составляет 75 символов. Самый короткий Python на данный момент?

1
ответ дан 26 November 2019 в 23:20
поделиться

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

... О, это не то, что вы имели в виду, когда сказали «Кодовый гольф: крестики-нолики»? ;) (введите цифры на цифровой клавиатуре, чтобы поставить крестики или нолики, т.е. 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
1
ответ дан 26 November 2019 в 23:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: