Xác định người chiến thắng Tic-Tac-Toe (dựa trên vòng)


26

Hãy chơi một số môn đánh gôn!

Thử thách là tìm ra người chiến thắng trong trò chơi Tic-Tac-Toe.

Điều này đã được thực hiện nhiều lần bằng cách đưa ra một bảng có một người chiến thắng rõ ràng nhưng đây là khuynh hướng:

Các ô được đánh số như thế này:

1|2|3
-+-+-
4|5|6
-+-+-
7|8|9

Bạn nhận được một mảng gồm 9 bước di chuyển như thế:

{3, 5, 6, 7, 9, 8, 1, 2, 3}

Điều này được phân tích cú pháp như sau:

  • Người chơi 1 đánh dấu ô 3
  • Người chơi 2 điểm ô 5
  • Người chơi 1 đánh dấu ô 6
  • Người chơi 2 điểm ô 7
  • Người chơi 1 đánh dấu ô 9
  • Người chơi 1 đã thắng

Lưu ý: Trò chơi không dừng lại sau khi một người chơi giành chiến thắng, có thể xảy ra việc người chơi thua quản lý để có được ba liên tiếp sau khi người chơi chiến thắng, nhưng chỉ có chiến thắng đầu tiên mới được tính.

Công việc của bạn bây giờ là lấy 9 số làm đầu vào và đầu ra cho người chơi chiến thắng và vòng mà trong đó chiến thắng xảy ra. Nếu không ai thắng, hãy xuất ra thứ gì đó không đổi theo lựa chọn của bạn. Bạn có thể nhận đầu vào và cung cấp đầu ra thông qua bất kỳ giá trị trung bình / định dạng tiêu chuẩn nào.

Chúc vui vẻ!

Một số ví dụ khác theo yêu cầu:

{2,3,4,5,6,7,1,8,9} => Player 2 wins in round 6
{1,2,4,5,6,7,3,8,9} => Player 2 wins in round 8
{1,2,3,5,4,7,6,8,9} => Player 2 wins in round 8

11
Chào mừng đến với PPCG! Đây là một bài đăng đầu tiên đẹp, nhưng thông thường chúng tôi không thích các định dạng đầu vào / đầu ra rất hạn chế . Bạn có cân nhắc loại bỏ "Người chơi X thắng trong vòng Y" và cho phép chúng tôi xuất ra ở bất kỳ định dạng hợp lý nào, như danh sách [X, Y]không? Trong trường hợp hòa, chúng ta có thể xuất bất kỳ giá trị phù hợp nào khác không? Tôi khuyên bạn nên như vậy, vì việc in những chuỗi chính xác đó không thực sự là một phần của việc chơi golf. Đối với những ý tưởng thử thách trong tương lai, tôi khuyên bạn nên sử dụng hộp cát . :-)
Ông Xcoder

Xin lỗi, xấu của tôi. Tôi nghĩ rằng nó là chính xác bây giờ.
Grunzwanzling

Đọc thử thách đến cùng, tôi nói rằng có thể có một trận hòa và bạn có thể đưa ra thứ gì đó bạn chọn khi nó xảy ra. Tôi trả lại {2,6} khi người chơi 2 thắng ở vòng 6 và {0,0} khi không có ai thắng.
Grunzwanzling

Chúng ta có thể sử dụng mọi thứ 0 không? (tế bào, người chơi, vòng đấu)
Arnauld

1
"Bạn nhận được một mảng gồm 9 bước di chuyển như vậy: {3, 5, 6, 7, 9, 8, 1, 2, 3}" - có 3thực sự xuất hiện hai lần không?
Jonathan Allan

Câu trả lời:


8

Võng mạc , 114 byte

(.)(.)
$1O$2X
^
123;;456;;789¶X
{`(.)(.*¶)(.)\1
$3$2
}`.*(.)(.)*\1(?<-2>.)*(?(2)(?!))\1.*¶(..)*
$1$#3
.*¶
T
T`d`Rd

Hãy thử trực tuyến! Dựa trên câu trả lời của tôi cho Tic-Tac-Toe - X hoặc O? . Xuất ra X<N>nếu người chơi thứ nhất thắng sau Nlượt, O<N>nếu người chơi thứ hai thắng, Tnếu không thắng. Giải trình:

(.)(.)
$1O$2X
^
123;;456;;789¶X

Tạo một bảng nội bộ, và cũng đánh dấu mỗi lần di chuyển với người chơi có di chuyển.

{`(.)(.*¶)(.)\1
$3$2

Áp dụng một động thái.

}`.*(.)(.)*\1(?<-2>.)*(?(2)(?!))\1.*¶(..)*
$1$#3

Tìm kiếm một chiến thắng, và nếu tìm thấy một chiến thắng, sau đó thay thế bảng bằng người chiến thắng và số lần di chuyển còn lại.

.*¶
T

Nếu các nước đi hết và không ai thắng thì trò chơi là hòa.

T`d`Rd

Tính số vòng từ số lần di chuyển còn lại.


4
Đây là một trong những câu trả lời .... khó hiểu hơn tôi từng thấy ở đây.
Lord Farquaad

6

MATL , 39 byte

3:g&+XIx"IX@oXK@(XIt!yXdyPXd&hK=Aa?KX@.

Đầu ra là

  • 1R, trong các dòng riêng biệt, nếu người dùng 1 thắng trong vòng R ;
  • 0R, trong các dòng riêng biệt, nếu người dùng 2 thắng trong vòng R ;
  • trống nếu không ai thắng.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

3:       % Push [1 2 3]
g        % Convert to logical. Gives [true true true]
&+       % Matrix of all pairs of additions. Gives a 3×3 matrix, which represents
         % the board in its initial state, namely all cells contain 2. This value
         % means "cell not used yet". 1 will represent "cell marked by user 1",
         % and 0 will represent "cell marked by user 2"
XI       % Copy into clipboard I
x        % Delete
"        % Implicit input: array with moves. For each move
  I      %   Push current board state
  X@     %   Push iteration index (starting at 1), that is, current round number
  o      %   Modulo 2: gives 1 or 0. This represents the current user
  XK     %   Copy into clipboard K
  @      %   Push current move ((that is, cell index)
  (      %   Write user identifier (1 or 0) into that cell. Cells are indexed
         %   linearly in column-major order. So the board is transposed compared
         %   to that in the challenge, but that is unimportant
  XI     %   Copy updated board into clipboard I
  t!     %   Duplicate and transpose
  y      %   Duplicate from below: push copy of board
  Xd     %   Extract main diagonal as a 3×1 vector
  y      %   Duplicate from below: push copy of transposed board
  PXd    %   Flip vertically and extract main diagonal. This is the anti-diagonal
         %   of the board
  &h     %   Concatenate stack horizontally. This concatenates the board (3×3),
         %   transposed board (3×3), main diagonal (3×1 vector) and anti-diagonal
         %   (3×1) into an 3×8 matrix
  K=     %   Push current user identifier. Test for equality with each entry of the
         %   3×8 matrix
  A      %   For each column, this gives true if all its entries are true. Note 
         %   that the first three columns in the 3×8 matrix are the board columns;
         %   the next three are the board rows; and the last two columns are the
         %   main diagonal and anti-diagonal. The result is a 1×8 vector
  a      %   True if any entry is true, meaning the current user has won
  ?      %   If true
    K    %     Push current user identifier
    X@   %     Push current round number
    .    %     Break for loop
         %   Implicit end
         % Implicit end
         % Implicit display

5

Javascript (ES6), 130 byte

m=>m.reduce((l,n,i)=>l||(b[n-1]=p=i%2+1,"012,345,678,036,147,258,048,246".replace(/\d/g,m=>b[m]).match(""+p+p+p)&&[p,i+1]),0,b=[])

f=m=>m.reduce((l,n,i)=>l||(b[n-1]=p=i%2+1,"012,345,678,036,147,258,048,246".replace(/\d/g,m=>b[m]).match(""+p+p+p)&&[p,i+1]),0,b=[])
console.log(JSON.stringify(f([3,5,6,7,9,8,1,2,3])))
console.log(JSON.stringify(f([2,3,4,5,6,7,1,8,9])))
console.log(JSON.stringify(f([1,2,4,5,6,7,3,8,9])))
console.log(JSON.stringify(f([1,2,3,5,4,7,6,8,9])))

Giải trình

m=>m.reduce((l,n,i)=>               // Reduce the input array with n as the current move
  l||(                              //  If there is already a winner, return it
  b[n-1]=p=i%2+1,                   //  Set the cell at b[n-1] to the current player p
  "012,345,678,036,147,258,048,246" //  For every digit in the list of possible rows:
    .replace(/\d/g,m=>b[m])         //   Replace it with the player at the cell
    .match(""+p+p+p)                //  If any of the rows is filled with p:
      &&[p,i+1]                     //   Return [p, current move]
),0,b=[])

Bạn có phiền khi cung cấp một lời giải thích hoặc một phiên bản không có ý thức xin vui lòng? Tôi quan tâm đến việc hiểu giải pháp của bạn.
Jack

4

Java (OpenJDK 8) , 445 byte

int[] t(int[]m){int[][]f=new int[3][3];boolean z=false;for(int i=0;i<9;i++){f[m[i]%3][m[i]/3]=z?2:1;if(f[m[i]%3][0]==(z?2:1)&&f[m[i]%3][1]==(z?2:1)&&f[m[i]%3][2]==(z?2:1)||f[0][m[i]/3]==(z?2:1)&&f[1][m[i]/3]==(z?2:1)&&f[2][m[i]/3]==(z?2:1)||m[i]%3+m[i]/3==2&&f[0][2]==(z?2:1)&&f[1][1]==(z?2:1)&&f[2][0]==(z?2:1)||m[i]%3==m[i]/3&&f[0][0]==(z?2:1)&&f[1][1]==(z?2:1)&&f[2][2]==(z?2:1)){return(new int[]{(z?2:1),++i});}z=!z;}return(new int[]{0,0});}

Hãy thử trực tuyến!

Giá trị trả về {1,8} có nghĩa là người chơi 1 đã thắng trong vòng 8. Giá trị trả về {0,0} có nghĩa là hòa.


5
Trừ khi bạn loại bỏ tất cả các khoảng cách không cần thiết, câu trả lời này được coi là không hợp lệ do thiếu nỗ lực chơi gôn. Hơn nữa, thật sự không nên trả lời thử thách của bạn nhanh như vậy và bạn có thể muốn thêm liên kết TIO để chúng tôi có thể kiểm tra mã của bạn.
Ông Xcoder

Liên kết tham khảo:
Ứng

Tôi xin lỗi, tôi đã sao chép điều sai. Thực tế nó ngắn hơn nhiều
Grunzwanzling

Bạn có thể xem các mẹo để chơi gôn trong câu hỏi Java để loại bỏ một số byte. Ví dụ falsecó thể được thay thế bởi 1<0và không gian sau lần đầu tiên ]có thể được loại bỏ.
dùng202729

438 byte . Ngoài ra, lý do tại sao phần "Header" và "Footer" tồn tại trên TIO là bạn không cần phải bình luận //Code that was submitted//End of code.
dùng202729

2

Kotlin , 236 byte

i.foldIndexed(l()to l()){o,(a,b),p->fun f(i:(Int)->Int)=b.groupBy(i).any{(_,v)->v.size>2}
if(f{(it-1)/3}|| f{it%3}|| listOf(l(1,5,9),l(3,5,7)).any{b.containsAll(it)}){return p%2+1 to o}
b to a+p}.let{null}
fun l(vararg l:Int)=l.toList()

Làm đẹp

    i.foldIndexed(l() to l()) { o, (a, b), p ->
        fun f(i: (Int) -> Int) = b.groupBy(i).any { (_, v) -> v.size > 2 }
        if (f { (it - 1) / 3 } || f { it % 3 } || listOf(l(1, 5, 9), l(3, 5, 7)).any { b.containsAll(it) }) {
            return p % 2 + 1 to o
        }
        b to a + p
    }.let { null }
fun l(vararg l:Int)= l.toList()

Kiểm tra

fun f(i: List<Int>): Pair<Int, Int>? =
i.foldIndexed(l()to l()){o,(a,b),p->fun f(i:(Int)->Int)=b.groupBy(i).any{(_,v)->v.size>2}
if(f{(it-1)/3}|| f{it%3}|| listOf(l(1,5,9),l(3,5,7)).any{b.containsAll(it)}){return p%2+1 to o}
b to a+p}.let{null}
fun l(vararg l:Int)=l.toList()

data class Test(val moves: List<Int>, val winner: Int, val move: Int)

val tests = listOf(
        Test(listOf(3, 5, 6, 7, 9, 8, 1, 2, 3), 1, 5),
        Test(listOf(2, 3, 4, 5, 6, 7, 1, 8, 9), 2, 6),
        Test(listOf(1, 2, 4, 5, 6, 7, 3, 8, 9), 2, 8),
        Test(listOf(1, 2, 3, 5, 4, 7, 6, 8, 9), 2, 8)
)

fun main(args: Array<String>) {
    tests.forEach { (input, winner, move) ->
        val result = f(input)
        if (result != winner to move) {
            throw AssertionError("$input ${winner to move} $result")
        }
    }
}

TIO

Dùng thử


1

Python 2 , 170 byte

q=map(input().index,range(1,10))
z=zip(*[iter(q)]*3)
o='',
for l in[q[2:7:2],q[::4]]+z+zip(*z):
 r=[n%2for n in l];y=all(r)*2+1-any(r)
 if y:o+=[max(l)+1,y],
print min(o)

Hãy thử trực tuyến!hoặc Thử tất cả các trường hợp thử nghiệm

#swap cell number / turn
q=map(input().index,range(1,10))
#split in 3 parts (rows)
z=zip(*[iter(q)]*3)
#starting value for the list with the results
#since string are "greater" than lists, this will
#be the output value when there is a draw
o='',
#iterate over diagonals, rows and columns
for l in[q[2:7:2],q[::4]]+z+zip(*z):
 #use %2 to separate between player 1 and 2
 r=[n%2 for n in l]
 #store in y the value of the player if the trio is a valid win, 0 otherwise
 #it's a win if all moves are from the same player
 y=all(r)*2+1-any(r)
 #if y has a valid player, add the highest turn of the trio, and the player to o
 if y:o+=[max(l)+1,y],
#output the smaller turn of the valid winning trios
print min(o)


1

Python 3.6+, 137 byte

n=m=c=z=0
for a in input():m+=1<<~-int(a);c+=1;z=z or f'{c&1}:{c}'*any(m&t==t for t in[7,56,448,73,146,292,273,84]);n,m=m,n
print(z or-1)

Định dạng đầu ra là winner number:roundhoặc -1cho một tie. Người chơi 2 là 0Người chơi 1 là 1. Nhập vào dưới dạng một chuỗi số chưa được tổng hợp của các số vuông 1 chỉ mục.


1

Thạch , 35 byte

9s3,ZU$$;ŒD$€Ẏf€⁸L€3e
s2ZÇƤ€ZFTḢ;Ḃ$

Một liên kết đơn âm lấy một danh sách các di chuyển và trả về một danh sách, [move, player]trong đó người chơi được xác định là 1(đầu tiên hành động) và 0(thứ hai để hành động).

Hãy thử trực tuyến!

Làm sao?

9s3,ZU$$;ŒD$€Ẏf€⁸L€3e - Link 1: any winning play?: list of player's moves:
9s3                   - (range of) nine split into threes = [[1,2,3],[4,5,6],[7,8,9]]
       $              - last two links as a monad:
      $               -   last two links as a monad:
    Z                 -     transpose = [[1,4,7],[2,5,8],[3,6,9]]
     U                -     upend     = [[7,4,1],[8,5,2],[9,6,3]]
   ,                  -  pair = [[[1,2,3],[4,5,6],[7,8,9]],[[7,4,1],[8,5,2],[9,6,3]]]
           $€         - last two links as a monad for €ach:
         ŒD           -   diagonals = [[1,5,9],[2,6],[3],[7],[4,8]] or [[7,5,3],[4,2],[1],[9],[8,6]]
        ;             -  concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,5,9],[2,6],[3],[7],[4,8]] or [[7,4,1],[8,5,2],[9,6,3],[7,5,3],[4,2],[1],[9],[8,6]]
             Ẏ        - tighten = [[1,2,3],[4,5,6],[7,8,9],[1,5,9],[2,6],[3],[7],[4,8],[7,4,1],[8,5,2],[9,6,3],[7,5,3],[4,2],[1],[9],[8,6]]
                      -    i.e.:    row1    row2    row3    diag\   x     x   x   x     col1    col2    col3    diag/   x     x   x   x
                      -    where x's are not long enough to matter for the rest...
                ⁸     - chain's left argument, list of player's moves
              f€      - filter to keep those moves for €ach of those lists to the left
                 L€   - length of €ach result
                   3e - 3 exists in that? (i.e. were any length 3 when filtered down to only moves made?)

s2ZÇƤ€ZFTḢ;Ḃ$ - Main link: list of the moves  e.g. [2,3,4,5,6,7,1,8,9]
s2            - split into twos                    [[2,3],[4,5],[6,7],[1,8],[9]]
  Z           - transpose                          [[2,4,6,1,9],[3,5,7,8]]
    Ƥ€        - for Ƥrefixes of €ach:
   Ç          -   call last link (1) as a monad     [0,0,0,0,0] [0,0,1,1]
      Z       - transpose                          [[0,0],[0,0],[0,1],[0,1],[0]]
       F      - flatten                            [0,0,0,0,0,1,0,1,0]
        T     - truthy indices                     [          6   8  ]
         Ḣ    - head (if empty yields 0)           6
            $ - last two links as a monad:
           Ḃ  -   modulo by 2 (evens are player 2) 0
          ;   -   concatenate                      [6,0]

0

Python 2, 168 byte

import itertools as z
f=lambda g:next(([i%2+1,i+1]for i in range(9) if any(c for c in z.combinations([[0,6,1,8,7,5,3,2,9,4][j]for j in g[i%2:i+1:2]],3)if sum(c)==15)),0)

Đầu ra (người chơi, vòng) hoặc 0 cho hòa.

Ánh xạ trò chơi lên một hình vuông ma thuật 3 nhân 3 và tìm kiếm bộ 3 Os hoặc X có tổng bằng 15.


0

Sạch , 244 ... 220 byte

import StdEnv
f[a,b]i#k= \l=or[and[isMember(c+n)(take i l)\\c<-:"123147159357"%(j,j+2)]\\j<-[0,3..9]&h<-:"\0\0",n<-[h-h,h,h+h]]
|k a=(1,i*2-1)|i>4=(0,0)|k b=(2,i*2)=f[a,b](i+1)
@l=f(map(map((!!)l))[[0,2..8],[1,3..7]])1

Hãy thử trực tuyến!

Chuỗi được lặp lại hchứa không thể in được và tương đương với "\003\001\000\000".


0

Python 2 , 140 136 134 byte

lambda a,i=0:i<9and(any(set(a[i%2:i+1:2])>=set(map(int,t))for t in'123 456 789 147 258 369 159 357'.split())and(i%2+1,i+1)or f(a,i+1))

Hãy thử trực tuyến!

EDIT: 4 byte + 2 byte thx cho Eric Outgolfer.

Xuất ra một tuple (playerNumber, roundNumber) hoặc Sai nếu không có người chiến thắng.



@Erik - Yah, tôi nên đã làm điều đó rồi; Nhưng tôi đang chiến đấu với bệnh cúm và mắt tôi bị đau :). Cám ơn!
Chas Brown

Vâng, sớm khỏe lại :)
Erik the Outgolfer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.