Tic-Tac-Toe - X ou O?

14

Contexte

Passez à "Tâche" si vous connaissez Tic-Tac-Toe (je pense que la plupart le sont!)

Tic-Tac-Toe est un célèbre jeu à deux joueurs. Il se compose d'un plateau 3x3 qui est rempli progressivement par deux joueurs (précisions ci-dessous); Le premier joueur utilise le personnage Xet l'autre utilise O. Le gagnant est le premier à obtenir 3 caractères consécutifs et identiques ( Xou O), horizontalement, verticalement ou en diagonale. Dans le cas où le plateau est rempli et qu'aucun des joueurs n'a réussi à obtenir trois personnages consécutifs comme décrit ci-dessus, le jeu se termine par une égalité. Notez qu'il peut y avoir des places vides à la fin de la partie, dans le cas où l'un des joueurs gagne en moins de 9 coups au total (cela ne peut pas se produire en cas d'égalité).

Tâche

Étant donné un tableau Tic-Tac-Toe à la fin d'une partie (sous la forme d'une chaîne, d'une matrice, d'une liste plate de 9 valeurs ordonnées, de tout autre format décent), déterminez qui gagne la partie.

  • L'entrée sera constituée de valeurs distinctes et cohérentes , une pour X, une pour Oet une autre qui représente un emplacement vide.

  • Votre programme devrait être capable de produire 3 valeurs distinctes, cohérentes et non vides: une au cas où il Xgagne, une autre au cas où il Ogagne ou une autre si les joueurs sont à égalité.

    Veuillez spécifier ces valeurs dans votre réponse. Vous pouvez supposer que l'entrée sera une carte Tic-Tac-Toe valide.

Cas de test

X, O, _Sont les valeurs d'entrée ici; X wins, O winsEt Tiesont pour la sortie.

X O X
O X _
O _ X

Sortie: X wins.

X _ O
X O _
X O X

Sortie: X wins.

X O X
_ O X
_ O _

Sortie: O wins.

X O X
O O X
X X O

Sortie: Tie.


Comme d'habitude, toutes nos règles standard s'appliquent. C'est le , le code le plus court en octets dans toutes les langues gagne!

M. Xcoder
la source
2
Sors de mon cerveau! J'ai juste eu une idée pour un défi Noughts & Crosses que j'allais à Sanbox lundi. Ensuite, j'ouvre le site et vois ça!
Shaggy
1
@Shaggy Pour citer quelqu'un de la série "Fast and Furious": Trop lent! ; p
M. Xcoder
C'est bon, mon idée était pour une version jouable, en supposant que cela n'a pas déjà été fait.
Shaggy
4
@Laikoni Je ne pense pas que ce soit une dupe, car cela a une entrée et une sortie beaucoup plus flexibles et a également des cases vides, et cela vous permet également de supposer que l'entrée est une carte valide.
Erik the Outgolfer
1
@Joshua Il s'agit de créer un jeu Tic-tac-toe. Il s'agit d'en classer un.
DonielF

Réponses:

6

Gelée ,  16 15  14 octets

U,Z;ŒD$€ẎḄỊÐḟḢ

Un lien monadique acceptant une liste de listes (les lignes - ou colonnes) avec les valeurs:

X = 0.155; O = -0.155; _ = 0

Retour des résultats:

X wins = 1.085; O wins = -1.085; Tie = 0

Remarque: en utilisant une valeur de zéro pour _, et des valeurs égales mais opposées pour Xet O, cette valeur (ici 0.155) peut être dans la plage (1/6, 1/7)(exclusive aux deux extrémités) - J'ai seulement choisi une valeur dans cette plage qui a donné un résultat en virgule flottante précisément représentable pour les cas de victoire.

Essayez-le en ligne!

Comment?

U,Z;ŒD$€ẎḄỊÐḟḢ - Link: list of lists (as described above)
U              - upend (reverse each row)
  Z            - transpose (get the columns)
 ,             - pair the two
      $€       - last two links as a monad for each of them:
    ŒD         -   diagonals (leading diagonals - notes: 1. only one is of length 3;
               -              2. the upend means we get the anti-diagonals too)
        Ẏ      - tighten (make a single list of all the rows, columns and diagonals)
         Ḅ     - from binary (vectorises) (note that [0.155, 0.155, 0.155]
               -                           converts to 4*0.155+2*0.155+1*0.155 = 1.085
               -                           and [-0.155, -0.155, -0.155]
               -                           converts to 4*-0.155+2*-0.155+1*-0.155 = -1.085
               -                           while shorter lists or those of length three
               -                           with any other mixtures of 0.155, -0.155 and 0
               -                           yield results between -1 and 1
               -                           e.g. [.155,.155,0] -> 0.93)
           Ðḟ  - filter discard if:
          Ị    -   insignificant (if abs(z) <= 1) (discards all non-winning results)
             Ḣ - head (yields the first value from the list or zero if it's empty)
Jonathan Allan
la source
Oui, je pense que toutes les réponses en langue ésotérique devraient avoir une explication (et j'aime aussi voir des explications pour les langues normales!)
Jonathan Allan
Merci de l'avoir ajouté! Très bonne approche, bien plus intelligente que ce que j'ai
pensé
6

Javascript (ES6), 103 87 octets

a=>"012+345+678+036+147+258+048+246T".replace(/\d/g,n=>a[n]||!1).match(/(\d)\1\1|T/)[0]

Contribution

  • X est représenté par 1
  • O est représenté par 2
  • _ est représenté comme 0

Production

  • X gagne est représenté par "111"
  • O wins est représenté par "000"
  • La cravate est représentée comme "T"

Explication

a=>
    "012+345+678+036+147+258+048+246" // List of indexes for each row
    .replace(/\d/g,n=>a[n]||!1)       // Replace all digits with the value of the cell
    .match(/(\d)\1\1|$/)[0]           // Find the first row filled with the same value

Cas de test

f=
a=>"012+345+678+036+147+258+048+246T".replace(/\d/g,n=>a[n]||!1).match(/(\d)\1\1|T/)[0]
console.log(f([1,2,1,2,1,0,2,0,1]))
console.log(f([1,0,2,1,2,0,1,2,1]))
console.log(f([1,2,1,0,2,1,0,2,0]))
console.log(f([1,2,1,2,2,1,1,1,2]))

Herman L
la source
"Votre programme devrait pouvoir sortir 3 valeurs distinctes, cohérentes et non vides ", donc vous ne pouvez pas sortir de chaîne vide pour tie.
RedClover
1
@Soaku Mon mauvais, j'ai raté cette partie des règles.
Herman L
4

Gelée , 18 octets

UŒD;;Z;ŒDµSA⁼3µÐfḢ

Essayez-le en ligne!

X= 1, O= -1, _= 0
X gagne = [1, 1, 1], O gagne = [-1, -1, -1], Tie = 0
Entrée sous forme de liste de 3 listes de 3 éléments dans (1, -1, 0)chacune.

Erik le Outgolfer
la source
Wow Nice ... Lorsque vous avez fini de jouer au golf, veuillez ajouter les valeurs d'E / S et une explication :-)
M. Xcoder
Voici une approche similaire avec un test légèrement plus court. Prend X= 1, O= 2, _= 3, renvoie 1(X gagne), 2(O gagne) ou 3(égalité).
Arnauld
@Arnauld merci pour le raccourcissement
Erik the Outgolfer
3

Python 3 , 73 octets

lambda b:{'XXX','OOO'}&{*b.split(),b[::4],b[1::4],b[2::4],b[::5],b[2::3]}

Essayez-le en ligne!


Python 2 , 100 95 92 87 82 77 octets

lambda b:{'XXX','OOO'}&set(b.split()+[b[::4],b[1::4],b[2::4],b[::5],b[2::3]])

Essayez-le en ligne!


Prend l'entrée comme une chaîne séparée par des sauts de ligne XO_

Les sorties:

  • {'XXX'}pour X,
  • {'OOO'} pour O
  • {} pour une cravate

Fonctionne en coupant la chaîne en colonnes, colonnes et diagonales:

The board:
    1 2 3
    4 5 6
    7 8 9
which is '123\n456\n789' is sliced into:

['123', '456', '789', '147', '258', '369', '159', '357']
rows: b.split() -> ['123', '456', '789']
cols: [b[::4],b[1::4],b[2::4]] -> ['147', '258', '369']
diag: [b[::5],b[2::3]] -> ['159', '357']

alors 'XXX'et'OOO'sont comparés aux tranches.

Prend l'entrée comme une chaîne séparée par des sauts de ligne XO_

Les sorties:

  • {'XXX'}pour X,
  • {'OOO'} pour O
  • {} pour une cravate

Fonctionne en coupant la chaîne en colonnes, colonnes et diagonales:

The board:
    1 2 3
    4 5 6
    7 8 9
which is '123\n456\n789' is sliced into:

['123', '456', '789', '147', '258', '369', '159', '357']
rows: b.split() -> ['123', '456', '789']
cols: [b[::4],b[1::4],b[2::4]] -> ['147', '258', '369']
diag: [b[::5],b[2::3]] -> ['159', '357']

puis 'XXX'et 'OOO'sont comparés aux tranches.

TFeld
la source
Python slicing FTW Quoi qu'il en soit, 81 octets devraient fonctionner, je pense.
2017 totalement humain
@icrieverytim [2::2]tranche 3579, tout en [2:8:2]donnant357
TFeld
Python 3, 73 octets .
Jonathan Frech
3

R, 118 116 115 octets

Merci à @ user2390246 pour deux octets supplémentaires.

function(M,b=table,u=unlist(c(apply(M,1,b),apply(M,2,b),b(diag(M)),b(M[2*1:3+1]))))`if`(any(u>2),names(u[u>2]),"T")

Légèrement non golfé:

function(M){
    u=unlist(c(apply(M,1,table), #Contingency table of the rows
             apply(M,2,table), #of the columns
             table(diag(M)), #of the diagonal
             table(M[2*1:3+1]))) #of the opposite diagonal
    `if`(any(u>2),names(u[u>2]),"T") #Give name of element that occurs more than twice in any setting
 }

Renvoie Xsi X gagne, Osi O gagne et Ten cas d'égalité.

Essayez-le en ligne!

plannapus
la source
1
M[c(3,5,7)]est plus court pour la diagonale opposée
user2390246
3

Perl 5 , 58 octets

Code de 56 octets + 2 fpr -p0 .

$_=eval sprintf'/(.)(.{%s}\1){2}/s||'x4 .'0?$1:T',0,2..4

Essayez-le en ligne!

Les sorties X et Opour les victoires, ou Tpour une égalité. Comprend un tas de code d'en-tête / pied de page pour tester tout à la fois.


Alternative, 58 octets

$}.="/(.)(.{$_}\\1){2}/s||"for 0,2..4;$_=eval$}.'0?$1:T'

Essayez-le en ligne!

Dom Hastings
la source
2

Python 2 , 124 118 117 117 115 octets

  • Enregistré six octets grâce à Erik l'Outgolfer ; en utilisant une chaîne pour éviter les virgules.
  • Enregistré un octet grâce à M. Xcoder ; jouer au golf[j*3:j*3+3] au à[j*3:][:3] .
  • Enregistré deux octets en utilisant un nombre magique pour compresser la chaîne.
def T(B):
 for j in range(8):
	a,b,c=map(int,`0x197bf3c88b2586f4bef6`[j*3:][:3])
	if B[a]==B[b]==B[c]>0:return B[a]

Essayez-le en ligne!

Valeurs d'entrée / sortie

  • X est représenté comme 1
  • O est représenté comme 2
  • _ est représenté comme None
Jonathan Frech
la source
[8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6]->map(int,'8036147258048246')
Erik the Outgolfer
@EriktheOutgolfer Merci. J'essayais de jouer à la liste entière en utilisant map(ord,"..."), bien qu'un nuloctet au milieu d'une chaîne n'ait pas fonctionné ...
Jonathan Frech
117 octets . [j*3:j*3+3]est [j*3:][:3]. En remarque, j*3+3c'est la même chose -~j*3, mais c'est aussi 118 octets.
M. Xcoder
@JonathanFrech Vous semblez avoir un extra 01234567...
Erik the Outgolfer
1
@ Mr.Xcoder Merci. J'ai appris un nouveau golf tranchant aujourd'hui.
Jonathan Frech
2

Python 3 , 173 octets

lambda x:h(x,1)*2or+h(x,0)
h=lambda x,y:g(x,y)or g(zip(*x),y)or x[0][0]==x[1][1]==x[2][2]==y or x[0][2]==x[1][1]==x[2][0]==y
g=lambda x,y:any(all(e==y for e in r)for r in x)

Essayez-le en ligne!

  • Entrée comme matrice de 1 == X, 0 == O, -1 == _

  • Sortie en tant que valeur unique: 2 == X, 1 == O, 0 == TIE

-8 octets grâce à Erik l'Outgolfer

HyperNeutrino
la source
Vous pouvez remplacer la première ligne par lambda x:h(x,1)*2or+h(x,0)-8 octets et 0 == TIE(ce qui est plus joli imo).
Erik the Outgolfer
@EriktheOutgolfer cool, merci
HyperNeutrino
2

PHP, 70 octets

for($c=95024101938;${${$i++&7}.=$argn[$c%9]}=1<$c/=3;);echo$XXX-$OOO;

Suppose -n(interprète par défaut). Nécessite en outre -R(exécuter<code> pour chaque ligne d'entrée), compté comme un.

L'entrée est prise sur une seule ligne (exactement comme dans la description du problème, sauf avec tous les espaces supprimés).

La sortie est la suivante: 1→ X Wins, -1→ O Wins, 0→ Tie.

Essayez-le en ligne!

primo
la source
Vous n'avez pas besoin d'avoir toutes les chaînes, vous pouvez choisir vos valeurs de sortie. 'X Wins'peut être changé en 'X'(ou même un entier - disons 1). Il en va de même pour 'O wins'et Tie. Cela étant dit, 109 octets .
M. Xcoder, du
@ Mr.Xcoder merci pour la clarification.
primo
1

Rétine , 49 octets

;
;;
.*(\w)(.)*\1(?<-2>.)*(?(2)(?!))\1.*
$1
..+
T

Essayez-le en ligne! Prend l'entrée sous la forme d'une chaîne de 11 caractères de 9 Xs, Os ou -s dans trois groupes de trois séparés par ;s, bien que le lien comprenne un en-tête qui traduit les cas de test donnés dans ce format. Fonctionne en faisant correspondre une ligne gagnante directement à l'aide d'un groupe d'équilibrage pour garantir que les trois caractères correspondants sont équidistants. (Les distances appropriées sont 0 (ligne horizontale), 4 (diagonale inversée), 5 (ligne verticale) ou 6 (diagonale); d'autres distances atteindraient ;ou s'étendraient en dehors de la chaîne.)

Neil
la source
1

Java 8, 112 108 106 104 90 102 93 bytes

b->b.replaceAll(".*(X|O)(\\1|...\\1...|.{4}\\1.{4}|..\\1..)\\1.*","$1").replaceAll("..+","T")

+12 octets (90 → 102) en raison d'une correction de bogue consistant à ne vérifier qu'une seule diagonale au lieu des deux.
-9 octets (102 → 93) en utilisant replaceAllau lieu dematches .

Entrée dans le format XOX OX_ O_X, la sortie X, OouT .

Explication:

Essayez-le ici.

b->{                   // Method with String as both parameter and return-type
  b.replaceAll(".*(X|O)(\\1|...\\1...|.{4}\\1.{4}|..\\1..)\\1.*",
                       //  If we found a line of X or O:
     "$1")             //   Replace it with either X or O
   .replaceAll("..+",  //  If there are now more than 2 characters left:
     "T")              //   Replace it with T
                       // End of method (implicit / single-line return-statement)

Explication regex:

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
.*                                      .*# 0 or more trailing & leading chars
  (X|O)                               \1  # X or O next to those leading/trailing chars
       (\1                                # A single X or O in between (row found)
          |...\1...                       # 3 chars, X or O, 3 chars (column found)
                   |.{4}\1.{4}            # 4 chars, X or O, 4 chars (diagonal TLBR found)
                              |..\1..)    # 2 chars, X or O, 2 chars (diagonal TRBL found)
Kevin Cruijssen
la source
0

Rétine , 127 octets

.*(X|O)\1\1.*
$1
(X|O).. \1.. \1..
$1
.(X|O). .\1. .\1.
$1
..(X|O) ..\1 ..\1
$1
(X|O).. .\1. ..\1
$1
..(X|O) .\1. \1..
$1
..+
_

Essayez-le en ligne!

... Je suppose que vous pourriez appeler cette force brute ... Je pensais qu'il pourrait y avoir un certain mérite ...

totalement humain
la source
0

Rétine , 51 octets

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
$1
..+
T

Port de ma réponse Java 8 . Entrée au format XOX OX_ O_X, sortie X,O ou T.

Explication:

Essayez-le ici.

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
.*                                      .*# 0 or more trailing & leading chars
  (X|O)                               \1  # X or O next to those leading/trailing chars
       (\1                                # A single X or O in between (row found)
          |...\1...                       # 3 chars, X or O, 3 chars (column found)
                   |.{4}\1.{4}            # 4 chars, X or O, 4 chars (diagonal TL→BR found)
                              |..\1..)    # 2 chars, X or O, 2 chars (diagonal TR→BL found)

$1                                        #  Replace match of above with either X or O

..+                                       # If there are now 2 or more characters left:
T                                         #  Replace everything with T
Kevin Cruijssen
la source
0

J, 34 octets

[:>./[:+./"1(2 1 0},:0 1 2}),(,|:)

Non golfé:

[: >./ [: +./"1 (2 1 0} ,: 0 1 2}) , (, |:)

Explication

Codage:

X = 2
O = 3
_ = 1

Notre stratégie de haut niveau consiste d'abord à créer une matrice dont chacune des rangées est une victoire possible. La ligne 1 est diagonale /, la ligne 2 est diagonale \, les trois lignes suivantes sont les lignes et les trois dernières lignes sont les colonnes. Cette partie est accomplie par la phrase (en utilisant le point Modifier }):

(2 1 0},:0 1 2}),(,|:)

Enfin, nous prenons le GCD de chaque ligne:

+./"1

Grâce à notre encodage, toute ligne avec un blanc aura un GCD de 1, de même que toute ligne contenant un mélange de X et d'O, car 2 et 3 sont coprimes. Donc, tout ce que nous devons faire ensuite est de trouver l'élément maximum:>./

Si le jeu est une égalité, ce sera 1. Si un joueur gagne, ce sera le numéro de ce joueur.

Essayez-le en ligne!

Jonas
la source
0

JavaScript, 66 octets

([a,b,c,d,e,f,g,h,i])=>e&(a&i|c&g|b&h|d&f)|a&(b&c|d&g)|i&(c&f|g&h)

Garder les choses simples.

  • Entrée: une chaîne ou un tableau de nombres ou de chaînes, avec 0 correspondant à un espace vide,1 un X et 2un O.
  • Sortie: 0pour une cravate,1 pour la victoire X,2 pour la victoire O.

Développé, légèrement commenté:

( [a,b,c,d,e,f,g,h,i] ) => // Break apart the input into nine variables w/ destructuring
  // Run through all possible win conditions. 1&1&1 -> 1, 2&2&2 -> 2
  e & (             // All victories involving the middle square
    a & i | c & g | // Diagonal lines
    b & h | d & f   // Vertical/horizontal through the middle
  ) | 
  a & ( b & c | d & g ) | // Victories with the top-left square
  i & ( c & f | g & h )   // Victories with the bottom-right square
Yair Rand
la source