三目並べ-XまたはO?


14

バックグラウンド

Tic-Tac-Toeに慣れている場合は、「タスク」に進んでください(ほとんどの人はそう思います!)

三目並べは有名な二人用ゲームです。それは、2人のプレイヤーによって徐々に満たされる3x3ボードで構成されます(以下の説明)。最初のプレイヤーはキャラクターXを使用し、他のプレイヤーはを使用しますO。勝者は、水平、垂直、または斜めに3つの連続した同一の文字(XまたはO)を最初に獲得します。ボードがいっぱいになり、上記のように3人の連続キャラクターを獲得できなかった場合、ゲームは同点で終了します。プレーヤーのいずれかが合計9回未満の動きで勝った場合、ゲームの終わりに空のスポットがあるかもしれないことに注意してください(これはタイの場合には起こりえません)。

仕事

ゲームの終わりにTic-Tac-Toeボード(文字列、マトリックス、9つの順序付けられた値のフラットリスト、その他の適切な形式)が与えられたら、誰がゲームに勝つかを決定します。

  • 入力は、一意の一貫した値で構成されますX。1つはO、もう1つは空のスポットを表します。

  • プログラムは、3つの異なる一貫した空でない値を出力できる必要があります。1つはX勝ち、もう1つは勝ち、もう1つOはプレイヤーが同点の場合です。

    回答にこれらの値を指定してください。入力が有効なTic-Tac-Toeボードであると想定できます。

テストケース

XO_ここで入力された値です。X winsO winsおよびTieは出力用です。

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
頭から出ろ!文字通り、私は月曜日にサンボックスになるつもりだったNoughts&Crossesチャレンジのアイデアを持っていました。次に、サイトをクラックして開きます。
シャギー

1
@Shaggy「Fast and Furious」シリーズから誰かを引用するには:遅すぎる!; p
Mr. Xcoder

大丈夫、私の考えは、まだ実行されていないことを前提に、プレイ可能なバージョンを目指していたことです。
シャギー

4
@Laikoniこれはだましだとは思いません。これは、入力と出力の柔軟性がはるかに高く、空のボックスもあるため、入力が有効なボードであると想定できるためです。
エリックアウトゴルファー

1
@Joshuaそれは三目並べゲームを作ることです。これはグレーディングについてです。
ドニエル

回答:


6

ゼリー 16 15  14 バイト

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

値を持つリスト(行または列)のリストを受け入れるモナドリンク:

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

結果を返す:

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

注:にゼロの値を使用し_、およびに等しいが反対の値を使用XしてO、この値(ここでは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)

はい、難解な言語の回答には説明が必要だと思います(そして、私は通常の言語の説明も見たいです!)
ジョナサンアラン

追加していただきありがとうございます!非常に良いアプローチ、私もで...ニースきたものよりも賢い方法
氏Xcoder

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つの異なる、一貫した、空でない値を出力できるはずです」ので、tieに空の文字列を出力することはできません。
RedClover

1
@Soaku私の悪い、ルールのその部分を見逃した。
ハーマンL

4

ゼリー、18バイト

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

オンラインでお試しください!

X= 1O= -1_= 0
X wins = [1, 1, 1]、O wins = [-1, -1, -1]、Tie = それぞれ0
3要素の3リストのリストとして入力(1, -1, 0)


すごい...ゴルフが終わったら、I / O値と説明を追加してください:-)
Mr. Xcoder

これは、テストがわずかに短い同様のアプローチです。Takes X= 1O= 2_= 31(X勝)、2(O勝)または3(タイ)を返します。
アーナルド

@Arnauld、短縮に感謝
エリック・ザ・アウトゴルファー

3

Python 3、73バイト

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

オンラインでお試しください!


パイソン2100の 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に2バイト追加していただきありがとうございます。

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
 }

XXが勝ったO場合、Oが勝っTた場合、および同点の場合に戻ります。

オンラインでお試しください!


1
M[c(3,5,7)]対角線の方が短い
-user2390246


2

パイソン2124の 118 117 115バイト

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')
エリック・ザ・アウトゴルファー

@EriktheOutgolferありがとう。私が使ってゴルフの整数のリストをしようとしていたmap(ord,"...")ものの、nul文字列の途中でバイトが...うまくいかなかった
ジョナサンFRECH

117バイト[j*3:j*3+3]です[j*3:][:3]。補足として、はとj*3+3同じですが-~j*3、これも118バイトです。
ミスターXcoder

あなたが余分に持っているように見える@JonathanFrech 01234567...
エリック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

Erik the Outgolferのおかげで-8バイト


最初の行をlambda x:h(x,1)*2or+h(x,0)-8バイトので置き換えることができます0 == TIE(これはきれいです)。
エリックアウトゴルファー

@EriktheOutgolferクール、ありがとう
HyperNeutrino

2

PHP、70バイト

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

想定-n(インタープリターのデフォルト)。さらに、1としてカウントされる(入力のすべての行に対して-R実行)が必要<code>です。

入力は1行で行われます(すべての空白が削除されていることを除き、問題の説明とまったく同じです)。

出力は次のとおりです。1→X Wins、-1→O Wins、0→Tie。

オンラインでお試しください!


文字列全体を保持する必要はありません。出力値を選択できます。'X Wins'に変更することができます'X'(または整数-など1)。同じことが'O wins'とにも当てはまりますTie。つまり、109バイトです。
ミスターXcoder

@ Mr.Xcoderは説明をありがとう。
プリモ

1

網膜、49バイト

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

オンラインでお試しください!リンクには、指定されたテストケースをこの形式に変換するヘッダーが含まれますが、入力は9 Xs、Os、または-sで区切られた3つのグループのsの11文字の文字列として取得され;ます。バランスグループを使用して勝ち線を直接一致させ、一致する3つの文字が等距離になるようにします。(適切な距離は、0(水平線)、4(逆対角線)、5(垂直線)、または6(対角線)です。他の距離は;、文字列に当たるか、文字列の外側に伸びます。)


1

Java 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、出力XOまたはで入力しますT

説明:

ここで試してみてください。

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、出力XOまたはで入力しますT

説明:

ここで試してみてください。

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

私たちの高レベルの戦略は、最初に各行が勝つ可能性のあるマトリックスを作成することです。行1は対角線/、行2は対角線\、次の3行は行、最後の3行は列です。この部分は、フレーズ(Item Amendを使用})によって実現されます。

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

最後に、各行のGCDを取得します。

+./"1

エンコードのおかげで、空白のある行はGCDが1になります。2と3は互いに素であるため、XとOが混在する行も同様です。したがって、次に行う必要があるのは、最大要素を見つけることだけです。>./

ゲームが同点の場合、それは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空白スペース、1X、および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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.