โอเอกซ์ - X หรือ O


14

พื้นหลัง

ข้ามไปที่ "งาน" หากคุณคุ้นเคยกับ Tic-Tac-Toe (ฉันคิดว่าส่วนใหญ่เป็น!)

Tic-Tac-Toeเป็นเกมที่มีผู้เล่นสองคนที่มีชื่อเสียง มันประกอบด้วยกระดาน3x3ที่เต็มไปด้วยผู้เล่นสองคนค่อยๆ ผู้เล่นคนแรกที่ใช้ตัวละครXและอื่น ๆ Oที่ใช้อย่างใดอย่างหนึ่ง ผู้ชนะคือคนแรกที่ได้รับ 3 ตัวละครติดต่อกันและเหมือนกัน ( XหรือO) ทั้งแนวนอนแนวตั้งหรือแนวทแยงมุม ในกรณีที่บอร์ดเต็มและไม่มีผู้เล่นคนใดจัดการตัวละครสามตัวติดต่อกันตามที่อธิบายไว้ข้างต้นเกมจะจบลงด้วยการเสมอกัน โปรดทราบว่าอาจมีจุดที่ว่างเปล่าในตอนท้ายของเกมในกรณีที่ผู้เล่นคนใดคนหนึ่งชนะในการเคลื่อนที่น้อยกว่า 9 ครั้ง (ไม่สามารถเกิดขึ้นได้ในกรณีที่เสมอกัน)

งาน

ให้บอร์ด Tic-Tac-Toe ในตอนท้ายของเกม (ในรูปแบบของสตริง, เมทริกซ์, รายการค่าคงที่ 9 ค่าสั่ง, รูปแบบที่เหมาะสมอื่น ๆ ), กำหนดผู้ชนะเกม

  • อินพุตจะประกอบด้วยค่าที่แตกต่างและสอดคล้องกันหนึ่งสำหรับXหนึ่งสำหรับหนึ่งOและอีกคนหนึ่งที่แสดงถึงจุดที่ว่างเปล่า

  • โปรแกรมของคุณควรจะสามารถส่งออก 3 ค่าที่ชัดเจนสอดคล้องและไม่ว่างเปล่า: หนึ่งรายการในกรณีXชนะ, อีกรายการหนึ่งในกรณีOชนะหรืออีกรายการหนึ่งหากผู้เล่นถูกผูกไว้

    โปรดระบุค่าเหล่านี้ในคำตอบของคุณ คุณสามารถสันนิษฐานได้ว่าอินพุตจะเป็นบอร์ด Tic-Tac-Toe ที่ถูกต้อง

กรณีทดสอบ

X, O, _มีค่าที่ป้อนเข้าที่นี่; X wins, O 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 ที่ฉันจะได้รับ Sanbox ในวันจันทร์ จากนั้นฉันก็เปิดเว็บไซต์แล้วดูนี่สิ!
ปุย

1
@Shaggy เพื่ออ้างอิงใครบางคนจากซีรี่ส์ "Fast and Furious": ช้าเกินไป! ; p
Mr. Xcoder

ไม่เป็นไรความคิดของฉันสำหรับรุ่นที่เล่นได้โดยสมมติว่ายังไม่ได้ทำ
Shaggy

4
@Laikoni ฉันไม่คิดว่ามันเป็นล่อเพราะมันมีความยืดหยุ่นในการป้อนข้อมูลและเอาท์พุทและมีกล่องว่างเปล่าเกินไปและสิ่งนี้ยังช่วยให้คุณสมมติว่าอินพุตเป็นบอร์ดที่ถูกต้อง
Erik the Outgolfer

1
@Joshua นั่นคือการทำเกมโอเอกซ์ นี่เป็นเรื่องเกี่ยวกับการให้เกรดหนึ่ง
DonielF

คำตอบ:


6

เยลลี่ ,  16 15  14 ไบต์

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

ลิงก์ monadic ยอมรับรายการของรายการ (แถว - หรือคอลัมน์) พร้อมค่า:

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)

ใช่ฉันคิดว่าคำตอบภาษาลึกลับใด ๆ ควรมีคำอธิบาย (และฉันต้องการดูคำอธิบายสำหรับภาษาปกติด้วย!)
Jonathan Allan

ขอบคุณที่เพิ่มมัน! วิธีการที่ดีมากวิธีที่ฉลาดกว่าที่ฉันเคยคิด ... Nice
Mr. 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 wins แสดงเป็น "111"
  • O wins จะแสดงเป็น "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

4

เยลลี่ขนาด 18 ไบต์

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

ลองออนไลน์!

X= 1, O= -1, _= 0
X wins = [1, 1, 1], O wins = [-1, -1, -1], Tie = 0
Input เป็นรายการ 3 รายการจาก 3 องค์ประกอบใน(1, -1, 0)แต่ละรายการ


ว้าวดี ... เมื่อคุณเล่นกอล์ฟเสร็จแล้วโปรดเพิ่มค่า I / O และคำอธิบาย :-)
Mr. Xcoder

นี่คือวิธีการที่คล้ายกันกับการทดสอบสั้นลงเล็กน้อย Takes X= 1, O= 2, _= 3, return 1(X wins), 2(O wins) หรือ3(tie)
Arnauld

@Arnauld ขอบคุณสำหรับการย่อ
Erik the Outgolfer

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 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 Anyways ขนาด 81 ไบต์ไว้ใช้งานได้
สิ้นเชิงมนุษย์

@icrieverytim แบ่ง[2::2]เป็น3579, ในขณะที่[2:8:2]ให้357
TFeld

งูหลามที่ 3, 73 ไบต์
Jonathan Frech

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

ungolfed เล็กน้อย:

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 ชนะOถ้า O ชนะและTในกรณีที่เสมอกัน

ลองออนไลน์!


1
M[c(3,5,7)]สั้นลงสำหรับทแยงมุมตรงข้าม
user2390246

3

Perl 5 , 58 ไบต์

56 ไบต์รหัส + 2 -p0FPR

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

ลองออนไลน์!

เอาท์พุทXและOสำหรับผู้ชนะหรือTเสมอกัน รวมถึงรหัสส่วนหัว / ส่วนท้ายเพื่อทดสอบทั้งหมดในครั้งเดียว


ทางเลือก 58 ไบต์

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

ลองออนไลน์!


2

Python 2 , 124 118 117 115 ไบต์

  • บันทึกหกไบต์ด้วยErik the Outgolfer ; ใช้สตริงเพื่อหลีกเลี่ยงคอมมา
  • ที่บันทึกไว้หนึ่งขอบคุณไบต์นาย 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ไบต์ในช่วงกลางของสตริงไม่ได้ทำงานออก ...
โจนาธาน Frech

117 ไบต์ เป็น[j*3:j*3+3] [j*3:][:3]ในฐานะที่เป็นบันทึกด้านข้างj*3+3เป็นเช่นเดียวกัน-~j*3แต่นั่นก็เป็น 118 ไบต์เช่นกัน
Mr. Xcoder

@JonathanFrech คุณดูเหมือนจะมีความพิเศษ01234567...
Erik the Outgolfer

1
@ Mr.Xcoder ขอบคุณ เรียนรู้การตีลูกกอล์ฟใหม่ในวันนี้
Jonathan Frech

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 ไบต์ขอบคุณ Erik the Outgolfer


คุณสามารถแทนที่บรรทัดแรกด้วย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 Wins, -1→ O Wins, 0→ Tie

ลองออนไลน์!


คุณไม่จำเป็นต้องมีสตริงทั้งหมดคุณสามารถเลือกค่าเอาต์พุตของคุณ 'X Wins'สามารถเปลี่ยนเป็น'X'(หรือแม้แต่จำนวนเต็ม - พูด1) เช่นเดียวกับและ'O wins' Tieที่ถูกกล่าวว่า109 ไบต์
Mr. Xcoder

@ Mr.Xcoder ขอบคุณสำหรับการชี้แจง
โม่

1

เรติน่า 49 ไบต์

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

ลองออนไลน์! รับอินพุตเป็นสตริง 11 อักขระของ 9 Xs, Os หรือ-s ในสามกลุ่มสามกลุ่มคั่นด้วย;s แม้ว่าลิงก์จะมีส่วนหัวซึ่งแปลกรณีทดสอบที่กำหนดเป็นรูปแบบนี้ ทำงานโดยการจับคู่ไลน์ที่ชนะโดยตรงโดยใช้กลุ่มการทรงตัวเพื่อให้แน่ใจว่าอักขระที่ตรงกันทั้งสามตัวมีความยาวเท่ากัน (ระยะทางที่เหมาะสมคือ 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การส่งออกX, หรือOT

คำอธิบาย:

ลองที่นี่

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)

คำอธิบาย 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)

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การส่งออกX, หรือOT

คำอธิบาย:

ลองที่นี่

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

Ungolfed:

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

คำอธิบาย

การเข้ารหัส:

X = 2
O = 3
_ = 1

กลยุทธ์ระดับสูงของเราคือการสร้างเมทริกซ์ก่อนซึ่งแต่ละแถวจะชนะได้ แถวที่หนึ่งคือแนวทแยงมุม / แถวที่ 2 คือแนวทแยง \, สามแถวถัดไปคือแถวและสามแถวสุดท้ายคือคอลัมน์ ส่วนนี้จะทำได้โดยวลี (ใช้การแก้ไขรายการ}):

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

ในที่สุดเราก็ใช้ GCD ของแต่ละแถว:

+./"1

ด้วยการเข้ารหัสของเราแถวใด ๆ ที่มีช่องว่างจะมี GCD เป็น 1 เช่นเดียวกับแถวใด ๆ ที่มี Xs และ Os ผสมกันเพราะ 2 และ 3 เป็น coprime ดังนั้นสิ่งที่เราต้องทำต่อไปคือหาองค์ประกอบสูงสุด:>./

หากเกมเสมอกันมันจะเป็น 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สำหรับผูก1สำหรับชัยชนะ X 2สำหรับชัยชนะ O

ขยายความเห็นเบา ๆ :

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