Словарь Tic Tac Toe

17

TicTacToeИгра может быть представлена в виде строки , обозначающее последовательность позиций , как игроки делают свой ход.

0 1 2
3 4 5
6 7 8

Предположим, Xвсегда играет первым.

Таким образом, строка «012345678» обозначает игру

XOX
OXO
XOX

Обратите внимание, что игра уже выиграна, когда игрок Xотмечает 6, в этот момент игра заканчивается, предоставляя выигрыш X. (т.е. игнорировать оставшиеся ходы, как только игрок выигрывает)

Ваша задача (код) - распечатать все игры (отсортированный порядок) и их результаты.

Формат

<movesequence>:<result>\n

например:

012345678:X
012345687:X
012345768:X
...

Обозначим Xвыигрыш первого игрока, Oвторого игрока и Dничьи.

Будет 9!(362880) игр.

Вот некоторые данные, чтобы проверить ваши результаты.

'X' Wins: 212256 
'O' Wins: 104544 
Draws : 46080 

Это Codegolf, и время выполнения должно быть в течение минуты. Веселиться!

РЕДАКТИРОВАТЬ: Удалил лишние детали и просто распечатать его stdout. Нет необходимости создавать файл.

st0le
источник
2
Я получаю разные цифры: 212256 побед для Х, 104544 побед для О и 46080 (и Википедия, похоже, со мной согласна ).
Вентеро
@ Ventero, я перепроверю, но я не вижу ссылки на эти цифры на странице.
st0le
@Ventero, ты прав, я отредактирую эту часть. скоро опубликует md5sum.
st0le
1
Ответ Ruby не самый короткий, поэтому он не должен быть принят в соответствии с вашими критериями оценки (code-golf).
mbomb007

Ответы:

3

Ruby 1.9, 201 символов

r=*[*l=0..8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6].each_slice(3)
w=->a{r.any?{|b|b&a==b}}
[*l].permutation(9){|a|u=[[],[]];i=-1
u[i%2]<<a[i+=1]while !((x=w[u[1]])||o=w[u[0]])&&i<8
puts a*""+":#{x ??X:o ??O:?D}"}

Слегка поиграл в гольф. Займет около 45 секунд, чтобы завершить здесь.

  • Изменить: (268 -> 249) Запись в стандартный вывод вместо файла
  • Редактировать: (249 -> 222) Не заполняйте массив ходами каждого игрока.
  • Изменить: (222 -> 208) Более короткий способ узнать, выиграл ли игрок
  • Изменить: (208 -> 213) Вернуться к 213, предыдущее решение было слишком медленным.
  • Изменить: (213 -> 201) Некоторые перестановки, удалены пробелы
Ventero
источник
Я немного отредактировал вопрос, вам не нужно создавать файл сейчас, просто распечатайте его.
st0le
4

J, 124 символа

((],~':',~1":[){&'DOX'@(</+2*>/)@:(<./"1)@:(((2{m/.@|.),(2{m/.),m"1,>./)"2)@(<:@(>:%2|]),:(%(2|>:)))@(3 3$]))"1((i.!9)A.i.9)

X победа, O победа и ничья подсчитывают.

Было немного больно отлаживать, хотя. :)

randomra
источник
3

Haskell, 224 222 персонажа

import Data.List
p=sort.permutations
a(e:_:z)=e:a z;a z=z
[c,d]%(e:z)|any((`elem`words"012 345 678 036 147 258 048 246").take 3).p.a.reverse$e=c|1<3=[d,c]%z;_%[]='D'
main=putStr$p['0'..'8']>>=(\s->s++':':"OX"%inits s:"\n")

Увы, permutationsфункция from Data.Listне производит перестановок в лексографическом порядке. Поэтому мне пришлось потратить 6 символов на сортировку.

MtnViewMark
источник
2

APL (139)

Это, вероятно, может быть сокращено больше, но это было достаточно сложно, как есть. Хотите верьте, хотите нет, но на моем компьютере он работает примерно за 45 секунд (исключая время, которое требуется для вывода всего, когда выводится на экран).

↑{⊃,/(,/⍕¨⍵-1),':',{1∊T←↑{∨/↑{⍵∘{⍵≡⍵∧⍺}¨↓⍉(9⍴2)⊤⎕UCS'㗀㐇㔤㑉㔑㑔'}¨↓(M∘.≥M)∧[2]M∊⍵}¨↓⍉5 2⍴0,⍨⍵:'XO'[1+</+/T]⋄'D'}⍵}¨↓{1≥⍴⍵:↑,↓⍵⋄↑⍪/⍵,∘∇¨⍵∘~¨⍵}M←⍳9

Объяснение:

  • M←⍳9: Сохраните в M числа от 1 до 9. Внутренне эта программа использует 1..9 вместо 0..8.
  • {... }: функция для получения всех перестановок:
    • 1≥⍴⍵:↑,↓⍵: если длина меньше или равна 1, вернуть аргумент в виде матрицы.
    • ⋄↑⍪/⍵,∘∇¨⍵∘~¨⍵: в противном случае удалите каждый символ из , получите его перестановки и добавьте его обратно.
  • ¨↓: для каждой перестановки ...
  • {... }: функция, которая дает победителя для этой перестановки:
    • ⊃,/(,/⍕¨⍵-1),':',{... }⍵: получить перестановку в виде строки со всеми числами, уменьшенными на 1 (чтобы получить требуемый вывод 0..8 вместо 1..9), за которым следует двоеточие, за которым следует символ, обозначающий победителя:
      • ⍉5 2⍴0,⍨⍵: отделить ходы X от ходов O. Поскольку у O один ход меньше X, это пространство заполнено 0, которое не используется и поэтому не влияет на результат.
      • {... }¨↓: и для доски X, и для доски O выполните следующую функцию, которая определяет, есть ли выигрыш на одном из девяти временных шагов:
        • (M∘.≥M)∧[2]M∊⍵: Создать битборд из чисел andходов , и этот битборд с цепочками битов 100000000, 110000000... 111111111чтобы получить состояние доски в каждый из девяти моментов времени.
        • {... }¨↓: для каждого из них запустите следующую функцию:
          • ⍉(9⍴2)⊤⎕UCS'㗀㐇㔤㑉㔑㑔': получить битборды для каждой возможной выигрышной ситуации
          • ⍵∘{⍵≡⍵∧⍺}¨↓: andкаждое состояние выигрыша с текущим битбордом и проверка, если указанное состояние выигрыша все еще существует
        • ∨/↑: orэто вместе, давая, есть ли победа на этой доске
      • 1∊T←↑: создайте матрицу 9x2 с 9-кратными временными шагами в первом ряду и 9-кратными временными шагами во втором ряду. Сохраните это в T. Если в этой матрице есть 1, кто-то выиграл.
      • :'XO'[1+</+/T]Если кто-то победил, дайте «Х» или «О» в зависимости от того, кто 1был первым.
      • ⋄'D': Если никто не победил, дайте 'D'.
  • : сделать из них матрицу, чтобы каждый из них отображался в отдельной строке.
Мэринус
источник
1

Python Ungolfed

from itertools import*
r=range
W=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]
def c(B):
    for i in r(8):
                if B[W[i][0]]==B[W[i][1]]==B[W[i][2]]:
                        return 1
        return 0

for i in permutations('012345678',9):
    B=[]
    for j in r(9):
        B.append(-(j+1))
    k=0
    F=1
    for j in r(9):
        k=[1,0][k]
        B[int(i[j])]=k
        if c(B):
            F=0
            break
    print "".join(i),':',[['0','X'][k],'D'][F]
fR0DDY
источник
вам не нужен второй параметр вpermutations
st0le
3
Пожалуйста, сыграйте в свою программу.
mbomb007
1

C ++ Ungolfed

#include<iostream>
using namespace std;
#include<algorithm>

int check(int B[])
{
        for (int i=0;i<3;i++)
                if ((B[3*i]==B[3*i+1]&&B[3*i]==B[3*i+2]) || (B[i]==B[i+3]&&B[i]==B[i+6]))
                        return 1;
        if ((B[2]==B[4]&&B[2]==B[6]) || (B[0]==B[4]&&B[0]==B[8]))
                return 1;
        return 0;               
}
int main()
{
        char c[11]="012345678";
        int B[9],i,j;
        do{
                for (i=0;i<9;i++)B[i]=-(i+1);
                for (i=0,j=1;i<9;i++,j=j?0:1)
                {
                        B[c[i]-'0']=j;
                        if (check(B))
                                break;
                }
                printf("%s:%c\n",c,i<9?j?'X':'O':'D');
        }while (next_permutation(c,c+9));
}
fR0DDY
источник
4
Пожалуйста, сыграйте в свою программу.
mbomb007
1

Python 2,7 (237)

from itertools import*
for z in permutations('012345678'):
 k,F=0,[9]*9
 for h in z:
    F[int(h)]=k=1-k
    if any(sum(a)in(0,3)for a in(F[:3],F[3:6],F[6:],F[::3],F[1::3],F[2::3],F[::4],F[2:8:2])):break
 else:k=2
 print"".join(z)+':','OXD'[k]
Даниил
источник