井字游戏-X或O?


14

背景

如果您熟悉井字游戏,请跳到“任务”(我想大多数人是!)

井字游戏是一款著名的两人游戏。它由一个3x3的棋盘组成,由两个玩家逐渐填充(以下说明);第一个玩家使用角色X,另一个使用O。获胜者是第一个获得水平,垂直或对角线连续3个相同字符(XO)的人。如果棋盘已满,并且没有一个玩家设法获得上述连续的三个角色,则游戏以平局结束。请注意,如果任一位玩家的胜利总数少于9步(如果出现平局,则不会发生),游戏结束时可能会有空位。

任务

给定游戏结束时的井字游戏板(以字符串,矩阵,9个有序值的平面列表以及任何其他体面格式的形式),确定谁赢了游戏。

  • 输入将包含不同且一致的值,一个表示X,一个表示O,另一个表示空白。

  • 您的程序应该能够输出3个不同的,一致的和非空的值:一个以防万一X,另一个以防万一O如果玩家并列,则为另一个。

    请在答案中指定这些值。您可以假定输入将是有效的井字游戏板。

测试用例

XO_在这里的输入值; X winsO winsTie用于输出。

X O X
O X _
O _ X

输出:X wins

X _ O
X O _
X O X

输出:X wins

X O X
_ O X
_ O _

输出:O wins

X O X
O O X
X X O

输出:Tie


与往常一样,我们所有的标准规则都适用。这是,每种语言中以字节为单位的最短代码胜出!


2
滚出我的大脑!从字面上看,我只是想过一个挑战,那就是星期一我要去桑伯克斯。然后,我打开网站并看到了!
毛茸茸的

1
@Shaggy引用“速度与激情”系列中的某个人:太慢了!; p
Xcoder先生17年

没关系,我的想法是要提供一个可播放的版本,假设还没有完成。
毛茸茸的

4
@Laikoni我不认为这是一个骗子,因为它具有更灵活的输入和输出方式,并且还具有空框,并且还可以让您假定输入是有效的电路板。
Erik the Outgolfer

1
@Joshua这是关于制作井字游戏。这是关于分级。
DonielF

Answers:


6

果冻 16 15  14 字节

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

单链链接,该列表接受具有以下值的列表(行或列)列表:

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

返回结果:

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

注:使用零值_,而大小相等方向相反的价值观XO,这个值(在这里0.155)可能范围内(1/6, 1/7)(不包括在两端) -我只给了一个精确表示的浮点结果范围内选择一个值对于胜利的情况。

在线尝试!

怎么样?

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

感谢您添加!很好的方法,比我想的要聪明得多...尼斯
Xcoder先生17年

6

Javascript(ES6),103 87字节

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

输入值

  • X表示为 1
  • O表示为 2
  • _表示为 0

输出量

  • X胜利表示为 "111"
  • O胜利表示为 "000"
  • 领带表示为 "T"

说明

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

测试用例

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]))


“您的程序应该能够输出3个不同的,一致的和非空的值 ”,因此您不能输出空字符串来打领带。
RedClover

1
@Soaku我不好,我错过了规则的那部分。
Herman L


3

Python 3,73个字节

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

在线尝试!


Python 2中100个 95 92 87 82 77字节

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

在线尝试!


将输入作为换行符分隔的字符串 XO_

输出:

  • {'XXX'}对于X
  • {'OOO'} 对于 O
  • {} 领带

通过将字符串切成行列和对角线来工作:

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']

然后'XXX''OOO'是针对切片检查。

将输入作为换行符分隔的字符串 XO_

输出:

  • {'XXX'}对于X
  • {'OOO'} 对于 O
  • {} 领带

通过将字符串切成行列和对角线来工作:

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']

然后'XXX''OOO'是针对切片检查。


我认为Python切片FTW无论如何,应该为81个字节
完全人类

@icrieverytim分割[2::2]3579,同时[2:8:2]给出357
TFeld


3

R,118个 116 115字节

感谢@ user2390246提供了两个额外的字节。

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")

略有偏差:

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
 }

X如果X获胜,OO 获胜,则返回T平局。

在线尝试!


1
M[c(3,5,7)]对角线的长度较短
user2390246'2-10-17

3

Perl 5、58字节

56字节代码+ 2 FPR -p0

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

在线尝试!

输出XO胜利,或T平局。包含一堆页眉/页脚代码以一次全部测试。


备用,58字节

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

在线尝试!


2

Python 2中124个 118 117 115字节

  • 节省了6个字节,多亏了暴走埃里克 ; 使用字符串来避免逗号。
  • 多亏了Xcoder先生,节省了一个字节;打高尔夫球[j*3:j*3+3][j*3:][:3]
  • 通过使用幻数压缩字符串来节省两个字节。
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]

在线尝试!

输入/输出值

  • X 表示为 1
  • O 表示为 2
  • _ 表示为 None

[8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6]->map(int,'8036147258048246')
暴民埃里克(Erik the Outgolfer)

@EriktheOutgolfer谢谢。我正在尝试使用来打高尔夫球整数列表map(ord,"..."),尽管nul字符串中间的一个字节不起作用...
Jonathan Frech

117个字节[j*3:j*3+3][j*3:][:3]。附带说明一下,j*3+3与相同-~j*3,但是也就是118个字节。
Xcoder先生17年

@JonathanFrech您似乎还有一个额外的机会01234567……
Egg the Outgolfer

1
@ Mr.Xcoder谢谢。今天学会了新的切片高尔夫球。
乔纳森·弗雷希

2

Python 3,173字节

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)

在线尝试!

  • 输入为 1 == X, 0 == O, -1 == _

  • 输出为单个值: 2 == X, 1 == O, 0 == TIE

-8字节归功于Outgolfer的Erik


您可以将第一行替换lambda x:h(x,1)*2or+h(x,0)为-8个字节和0 == TIE(这是更漂亮的imo)。
Erik the Outgolfer

@EriktheOutgolfer很酷,谢谢
HyperNeutrino

2

PHP,70个字节

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

假设-n(解释器默认值)。附加要求-R(执行<code>对输入的每一行),计为一个。

输入是在一行上进行的(与问题描述中的描述完全相同,除了所有空白都已删除)。

输出如下:1→X胜,-1→O胜,0 →并列。

在线尝试!


您不需要整个字符串,可以选择输出值。'X Wins'可以更改为'X'(甚至是整数-例如1)。'O wins'和和相同Tie。就是说109个字节
Xcoder先生17年

@ Mr.Xcoder感谢您的澄清。
primo

1

视网膜,49字节

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

在线尝试!将输入作为由9 XOs或-s组成的11个字符的字符串,分为3组,每组3个,以;s 分隔,尽管该链接包含一个标头,该标头将给定的测试用例转换为这种格式。通过使用平衡组直接匹配获胜线来工作,以确保三个匹配的字符是等距的。(合适的距离是0(水平线),4(反对角线),5(垂直线)或6(对角线;其他距离会碰到a ;或延伸到弦外)。


1

爪哇8,112 108 106 104 90个 102 93个字节

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

+12字节(90→102),这是因为仅修复了一个对角线而不是两个对角线的错误修复。
-9字节(102→93)通过使用replaceAll代替matches

输入格式XOX OX_ O_X,输出XOT

说明:

在这里尝试。

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)

正则表达式说明:

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

0

视网膜,127字节

.*(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
..+
_

在线尝试!

...我想你可以称呼这种蛮力...以为可能有一些优点...


0

视网膜,51字节

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

我的Java 8答案端口。输入格式XOX OX_ O_X,输出XOT

说明:

在这里尝试。

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

0

J,34个字节

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

取消高尔夫:

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

说明

编码方式:

X = 2
O = 3
_ = 1

我们的高级策略是首先创建一个矩阵,每个矩阵都有可能获胜。第一行是对角线/,第二行是对角线\,接下来的三行是行,最后三行是列。这部分由以下短语完成(使用Item Amend }):

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

最后,我们获取每行的GCD:

+./"1

多亏了我们的编码,任何带有空白的行的GCD都会为1,因为包含2和3都是互质的,所以包含X和O的任何行都将具有GCD。因此,我们接下来要做的就是找到最大元素:>./

如果游戏是平局,则为1。如果玩家获胜,则为该玩家的号码。

在线尝试!


0

JavaScript,66个字节

([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)

保持简单。

  • 输入:一个字符串或数字或字符串数​​组,分别0对应一个空格,1一个X和2一个O。
  • 输出:0平局,1X胜利,2O胜利。

展开,轻轻评论:

( [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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.