Xác định chiến thắng trong Tictactoe


19

Hãy chơi một số mã golf!

Cho một trạng thái bảng tic-tac-toe (Ví dụ :)

|x|x|o|
|x|o|x|
|o|o|x|

Xác định xem một trò chơi là winmột losehay cat. Mã của bạn sẽ xuất ra bất kỳ tùy chọn nào trong số các tùy chọn này. Trò chơi trên nên xuấtlose

Nói rõ hơn: một chiến thắng được định nghĩa là bất kỳ 3 xgiây liên tiếp (đường chéo, ngang, dọc). thua là 3 ogiây liên tiếp, trong khi cattrò chơi không có gì liên tiếp.

Để làm cho mọi thứ thú vị, bạn có thể xác định cấu trúc đầu vào của mình cho trạng thái - sau đó bạn phải giải thích. Chẳng hạn, xxoxoxooxtrạng thái hợp lệ như đã thấy ở trên, trong đó mỗi ký tự được đọc từ trái sang phải, từ trên xuống dưới. [['x','x','o'],['x','o','x'],['o','o','x']]là trò chơi trong mảng đa chiều đọc theo cách tương tự. Trong khi 0x1a9đó là hex cho 110101001có thể hoạt động như một nén phù hợp, nơi 1có thể được thao tác cho xs và 0có thể được thao tác cho o.

Nhưng đó chỉ là một số ý tưởng, tôi chắc chắn bạn có thể có nhiều ý tưởng của riêng bạn.

Luật Đường bộ:

  1. Chương trình của bạn phải có khả năng chấp nhận bất kỳ trạng thái khả thi nào.
  2. Các hình thức đầu vào phải có thể đại diện cho bất kỳ trạng thái.
  3. "Trạng thái thắng phải được xác định từ hội đồng quản trị"
  4. Giả sử một bảng hoàn chỉnh
  5. Winloseví dụ trước trong trường hợp 'xxxoooxxx'

Số lượng nhân vật thấp nhất sẽ thắng


1
Tôi thích cấu trúc đầu vào này : (win|lose|cat) [xo]{9}, trong đó từ đầu tiên biểu thị trò chơi là thắng, thua hay mèo (?) Cho người chơi x. Có thể đại diện cho bất kỳ nhà nước.
Runer112

2
Tôi có thể đề xuất một quy tắc như "Trạng thái thắng phải được xác định từ bảng" hoặc "Đầu vào phải không chứa thông tin ngoại trừ trạng thái bảng"?
undergroundmonorail

3
Có phải chúng ta giả sử chỉ chơi trò chơi hợp pháp? Nếu vậy, một số trạng thái nhất định sẽ là không thể, ví dụ: XXX OOO XXX nhưng nếu không, một số trạng thái toàn bảng bao gồm điều này là kết quả không thể thứ tư, trong đó X thắng nhưng O cũng thắng.
Bạo loạn

10
Tại sao "mèo" không quan tâm?
Chris

7
@DylanMadisetti: chưa bao giờ nghe thấy điều đó trước đây và googlign cho "win win cat" không đưa ra được gì. Tôi đã đi với cà vạt hoặc vẽ cá nhân. Hoặc trong trường hợp của trò chơi này có thể "không thể tránh khỏi". ;-) Tôi không bận tâm lắm về cuộc thi. Một chuỗi là một chuỗi. ;-)
Chris

Câu trả lời:


11

Ruby 2.0, 85 ký tự

Đây là một giải pháp dựa trên bitmask đơn giản trong Ruby:

d=gets.hex
$><<[292,146,73,448,56,7,273,84].map{|m|d&m<1?:lose:d&m<m ?:cat: :win}.max

Bảng được biểu diễn dưới dạng số hex, được tạo thành từ chín bit tương ứng với chín ô vuông. 1 là một X, 0 là một O. Điều này giống như 0x1a9ví dụ trong câu hỏi, mặc dù 0xlà tùy chọn!

Có lẽ có một cách tốt hơn để làm bitmasks sau đó chỉ cần mã hóa một danh sách lớn. Tôi sẽ vui vẻ góp ý.

Xem nó chạy trên Ideone ở đây .


1
Danh sách của bạn chứa 273hai lần. Và tôi thực sự thích maxý tưởng!
Ventero

1
Ôi @Ventero, luôn luôn với những tối ưu hóa tối nghĩa (cảm ơn)
Paul Prestidge

Có thể có không gian trống trên một bảng. Định dạng đầu vào của bạn không tính đến điều này và do đó không thể đại diện cho bất kỳ trạng thái trò chơi khả thi nào.
Stephen Ostermiller

2
@StephenOstermiller quy tắc 4: giả sử một bảng hoàn chỉnh. Bạn đúng rằng quy tắc này có lẽ mâu thuẫn với quy tắc 1 và 2, tuy nhiên nếu bạn đọc tất cả các ý kiến ​​về câu hỏi tôi nghĩ rằng điều này nằm trong tinh thần của câu hỏi (bảng không hoàn chỉnh không được bảo hiểm, trong khi bảng hoàn chỉnh nhưng không hợp lệ.) Tuy nhiên tôi nghĩ rằng bát phân sẽ là một định dạng đầu vào thân thiện với người dùng hơn hex.
Cấp sông St

1
Có nó, tôi nghĩ hoàn thành có nghĩa là một cái gì đó khác nhau.
Stephen Ostermiller

10

Toán học, 84 ký tự

a=Input[];Which[Max@#>2,win,Min@#<1,lose,1>0,cat]&@{Tr@a,Tr@Reverse@a,Tr/@a,Total@a}

Định dạng đầu vào: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}


Chuyện gì đang xảy ra ở đây vậy?
xem

3
@TheRare Bắt đầu từ bên phải. Tr@alà dấu vết của trường (tổng trên đường chéo), Tr@Reverse@alà dấu vết của trường bị lật (một số trên đường chéo), Tr/@ađược Tráp dụng cho mỗi hàng, cung cấp cho bạn tổng trên mỗi hàng, Total@acung cấp cho bạn tổng trên mỗi cột. Về cơ bản, bạn đã có tất cả 8 dòng bạn cần kiểm tra. Sau đó, Whichđiều được áp dụng cho điều đó (về cơ bản là một if/elseif/elsetuyên bố), trong đó #đại diện cho danh sách 8 giá trị đó. ifcó một 3bạn thắng, else ifcó một 0bạn thua, else if 1>0(đúng) cat.
Martin Ender

6

Bash: 283 262 258

Với giao diện tương đối thân thiện.

t(){ sed 's/X/true/g;s/O/false/g'<<<$@;}
y(){ t $(sed 's/X/Q/g;s/O/X/g;s/Q/O/g'<<<$@);}
f(){($1&&$2&&$3)||($1&&$5&&$9)||($1&&$4&&$7)||($2&&$5&&$8)||($3&&$5&&$7)||($3&&$6&&$9)||($4&&$5&&$6)||($7&&$8&&$9)}
f $(t $@)&&echo win||(f $(y $@)&&echo lose)||echo cat

Để thực thi bash tictactoe.sh O X O X O X X O X

Lưu ý: danh sách 9 vị trí là biểu diễn ma trận chuẩn. Sẽ không có vấn đề gì nếu bảng được biểu diễn dưới dạng cột chính hoặc hàng chính, đọc từ trái sang phải hoặc từ trên xuống dưới - trò chơi của noughts và cross (hoặc tic tac toe nếu bạn nhấn mạnh) là đối xứng, vì vậy thứ tự đầu vào không liên quan cho kết quả trong mỗi lần thực hiện chính xác, miễn là đầu vào là tuyến tính.

Chỉnh sửa: Nhờ hjk cho đề xuất cú pháp chức năng ngắn hơn.


Cân nhắc t() { ... }thay function t? Có thể lưu một số nhân vật ở đó. :)
hjk

Tôi hoàn toàn quên mất cú pháp hàm thay thế - cảm ơn!
Bạo loạn

Không gian không được yêu cầu xung quanh <<<để lưu bốn ký tự khác.
Michael Mior

4

Befunge 93 - 375

Lấy một chuỗi nhị phân làm đầu vào.

99>~\1-:!!|>v  
>0v>v>v   >^$>v
^+ + +    0<:p:
>#+#+#+    ^246
^+ + +    0<265
>#+#+#+    ^pp6
^+ + +    0<2++
 #+#+#+     55p
   0 0      552
  >^>^>0v   +46
v+ + +  <   ppp
>0 + + + v  444
   v!!-3:<< 246
  v_"ni"v   ppp
  0v" w"<   :+:
  \>,,,,@   266
  ->,,,@    555
  !^"cat"_^ 645
  !>:9-! ^  +:+
  >|        p:p
   >"eso"v  6p6
 @,,,,"l"<  246
            p2p
            >^ 
  v       <^  <

Đọc chuỗi. Bruteforce viết nó (dải dọc nhất bên phải) dưới dạng ma trận ở giữa

^+ + + 
>#+#+#+
^+ + + 
>#+#+#+
^+ + + 
 #+#+#+

thêm mạng tinh thể (idk). Xác định tổng của các cột, hàng và hai chẩn đoán. So sánh các giá trị đó với 3 ("thắng") hoặc 0 ("thua"), nếu không, nếu tất cả các giá trị bằng 1 hoặc 2 thì rút ra ("mèo").


4

GolfScript, 27 ký tự

70&.{~"win""lose"if}"cat"if

Định dạng đầu vào là một chuỗi bao gồm tám chữ số bát phân, mỗi chữ số (dự phòng) mã hóa ba ô vuông liên tiếp:

  • Ba chữ số đầu tiên, mỗi chữ số mã hóa một hàng của bảng, từ trên xuống và từ trái sang phải.
  • Ba chữ số sau đây mỗi chữ số mã hóa một cột duy nhất của bảng, từ trái sang phải và từ trên xuống.
  • Hai chữ số cuối cùng, mỗi chữ số mã hóa một trong các đường chéo (đầu tiên từ trên cùng bên trái xuống dưới cùng bên phải, sau đó từ dưới cùng bên trái sang trên cùng bên phải).

Để mã hóa một chuỗi (hàng / cột / đường chéo) của ba hình vuông dưới dạng một chữ số bát phân, thay thế mỗi xtrong chuỗi bằng 1 và mỗi obằng 0 và diễn giải chuỗi kết quả của một và các số 0 dưới dạng số nhị phân từ 0 đến 7 đã bao gồm.

Định dạng đầu vào này khá dư thừa (tất cả các vị trí bảng được mã hóa ít nhất hai lần, với vị trí trung tâm được mã hóa bốn lần), nhưng nó thể hiện rõ ràng bất kỳ trạng thái có thể nào của bảng tic-tac-toe hoàn toàn và không được mã hóa trực tiếp người chiến thắng vào đầu vào.

Đầu vào có thể, tùy ý, chứa khoảng trắng hoặc dấu phân cách khác giữa các chữ số. Trong thực tế, tất cả các chương trình thực sự quan tâm là liệu chuỗi đầu vào có chứa các chữ số 7hay không 0.

Ví dụ: bảng ví dụ:

|x|x|o|
|x|o|x|
|o|o|x|

có thể được đại diện bởi đầu vào:

651 643 50

Để thuận tiện, đây là chương trình GolfScript để chuyển đổi bố cục bảng nghệ thuật ASCII, như thể hiện trong thử thách ở trên, thành chuỗi đầu vào phù hợp với chương trình này:

."XOxo"--[{1&!}/]:a[3/.zip"048642"{15&a=}%3/]{{2base""+}%}%" "*

Bộ chuyển đổi này bỏ qua bất kỳ ký tự nào ngoài xo, trong cả hai trường hợp, trong đầu vào của nó. Nó tạo ra một chuỗi một chữ số (hoàn chỉnh với các dấu phân cách không gian như được hiển thị ở trên) phù hợp để đưa vào chương trình xác định thắng ở trên, do đó, việc ghép hai chương trình này có thể được sử dụng để xác định người chiến thắng trực tiếp từ hội đồng nghệ thuật ASCII.

Ngoài ra, đây là một trình chuyển đổi ngược, chỉ để chứng minh rằng đầu vào thực sự không đại diện rõ ràng cho bảng:

.56,48>-- 3<{2base-3>{"ox"=}%n}%"|".@@*+);

Thi thiên Đây là một bản demo trực tuyến của giải pháp này.


2
Định dạng đầu vào có vẻ giống như một mánh gian lận vì phần lớn công việc xảy ra trong quá trình sản xuất đầu vào.
Arkku

@Arkku: Vâng, đúng vậy, nhưng câu hỏi nói rõ ràng rằng "bạn có thể xác định cấu trúc đầu vào của mình cho trạng thái - sau đó bạn phải giải thích." Nó thậm chí còn hiển thị một chuỗi hex được đóng gói bit như một ví dụ về định dạng đầu vào hợp lệ; sự khác biệt duy nhất giữa đó và định dạng đầu vào của tôi là tôi sắp xếp lại và sao chép một số bit.
Ilmari Karonen

6
Nó chính xác là sự trùng lặp có vẻ như là một mánh gian lận. (ví dụ, nó không trực tiếp mã hóa các chiến thắng như sự hiện diện của 7 hoặc 0 trong dữ liệu)
Arkku

Vẫn là một mã hóa thông minh, nó không cần thiết, nhưng làm cho việc tìm kiếm giải pháp hiệu quả hơn nhiều so với bất kỳ mã hóa không dự phòng nào!
ARRG

3

Python 2 - 214 byte

b=eval(raw_input())
s=map(sum,b)
w,l='win','lose'
e="if min(s)<1:print l;a\nif max(s)>2:print w;a"
exec e+'\ns=map(sum,zip(*b))\n'+e
m=b[1][1]
for i in 0,2:
 if m==b[0][i]==b[2][abs(i-2)]:print[l,w][m];a
print'cat'

Tôi chắc chắn có những cải tiến sẽ được thực hiện.

Chạy:

python2 tictactoe.py <<< '[[1,1,1],[1,0,1],[0,1,0]]'

đại diện cho bảng này:

X|X|X
-----
X|O|X
-----
0|X|0

Lối thoát với một NameErrorngoại lệ trong mọi trường hợp ngoại trừ cat.


Whoa, tôi chưa bao giờ biết về <<<! +1 chỉ cho điều đó.
Greg Hewgill

@GregHewgill Thật tiện lợi. ./whatever <<< 'blah blah blah'cũng giống như echo -n 'blah blah blah' | ./whatevernhưng mà không phải là một quá trình hoàn toàn riêng biệt cho echo.
undergroundmonorail

@undergroundmonorail echoin bashthực sự là một nội dung, vì vậy không kết thúc một quy trình mới
Bob

@GregHewgill, nó được gọi là herestring

3

Haskell, 146 ký tự

Để làm cho mọi thứ thú vị, bạn có thể xác định cấu trúc đầu vào của mình cho trạng thái - sau đó bạn phải giải thích.

ĐƯỢC :). Đại diện của tôi trong một bảng là một trong số 126 ký tự đó

ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌

Đây là giải pháp trong 146 ký tự:

main=interact$(\x->case(head x)of h|elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌"->"lose";h|elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ"->"cat";h->"win")

Và đây là cách nó hoạt động, như một kịch bản haskell:

import Data.List (subsequences, (\\))
import Data.Char (chr)

-- A set of indexes [0-8] describing where on the board pieces of a single color have been played
-- For example the board "OxO;Oxx;xxO" is indexes [0,2,3,8]
type Play = [Int]

-- There are 126 filled tic tac toe boards when X plays first.
--      (This is a combination of 4 OHs among 9 places : binomial(9 4) = 126)
-- perms returns a list of all such possible boards (represented by the index of their OHs).
perms = filter (\x -> 4 == length x) $ subsequences [0..8]

-- We now create an encoding for plays that brings them down to a single char.
-- The index list can be seen as an 9 bit binary word [0,2,3,8] -> '100001101'
-- This, in turn is the integer 269. The possible boards give integers between 15 and 480.
-- Let's call those PlayInts
type PlayInt = Int

permToInt [] = 0
permToInt (x:xs) = (2 ^ x) + permToInt xs 

-- Since the characters in the range 15-480 are not all printable. We offset the chars by 300, this gives the range 
-- ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌
-- Of all distinct, printable characters
uOffset = 300

-- Transform a PlayInt to its Char representation
pIntToUnicode i = chr $ i + uOffset

-- Helper function to convert a board in a more user friendly representation to its Char
-- This accepts a representation in the form "xooxxxoxo"
convertBoard s = let play = map snd $ filter (\(c, i) -> c == 'o') $ (zip s [0..]) :: Play 
    in pIntToUnicode $ permToInt play

--
-- Now let's cook some data for our final result
--  

-- All boards as chars
allUnicode = let allInts = map permToInt perms 
    in map pIntToUnicode allInts

-- Now let's determine which boards give which outcome.

-- These are all lines, columns, and diags that give a win when filled
wins = [
        [0,1,2],[3,4,5],[6,7,8], -- lines
        [0,3,6],[1,4,7],[2,5,8], -- columns
        [0,4,8],[2,4,6] -- diagonals
    ]

isWin :: Play -> Bool   
isWin ps = let triplets = filter (\x -> 3 == length x) $ subsequences ps -- extract all triplets in the 4 or 5 moves played
    in any (\t -> t `elem` wins) triplets -- And check if any is a win line

-- These are OH wins
oWins = filter isWin perms
-- EX wins when the complement board wins
xWins = filter (isWin . complement) perms
    where complement ps = [0..9] \\ ps
-- And it's stalemate otherwise
cWins = (perms \\ oWins) \\ xWins

-- Write the cooked data to files
cookData = let toString = map (pIntToUnicode . permToInt) in do
  writeFile "all.txt" allUnicode
  writeFile "cWins.txt" $ toString cWins
  writeFile "oWins.txt" $ toString oWins
  writeFile "xWins.txt" $ toString xWins

-- Now we know that there are 48 OH-wins, 16 stalemates, and 62 EX wins (they have more because they play 5 times instead of 4).
-- Finding the solution is just checking to which set an input board belongs to (ungolfed :)
main = interact $ \x -> case (head x) of -- Only consider the first input char
    h | elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌" -> "lose" -- This string is == oWins
    h | elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ" -> "cat" -- And this one == cWins
    h -> "win"

3

JavaScript, 420 ký tự

if((s&0x3F000)==0x3F000||(s&0x00FC0)==0x00FC0||(s&0x0003F)==0x0003F||(s&0x030C3)==0x030C3||(s&0x0C30C)==0x0C30C||(s&0x30C30)==0x30C30||(s&0x03330)==0x03330||(s&0x30303)==0x30303)return 'win'
if((s&0x3F000)==0x2A000||(s&0x00FC0)==0x00A80||(s&0x0003F)==0x0002A||(s&0x030C3)==0x02082||(s&0x0C30C)==0x08208||(s&0x30C30)==0x20820||(s&0x03330)==0x02220||(s&0x30303)==0x20202)return 'lose'
if((s&0x2AAAA)==0x2AAAA)return 'cat'

Trong phiên bản này, schứa một số nguyên biểu thị trạng thái của bảng trò chơi. Đó là một mảng giá trị trong đó hai bit đại diện cho mỗi ô vuông trên bảng:

  • 10 - X
  • 11 - Ôi
  • 00 - Hình vuông trống

Giải pháp này sử dụng thao tác bit để kiểm tra từng cấu hình "ba liên tiếp" có thể (nó kiểm tra chúng hai lần, một lần cho X và một lần cho O).

Tôi trình bày điều này với sự thu nhỏ từ trang web Tic-Tac-Toe của tôi , nơi detectWinchức năng này được sử dụng như một phần của trò chơi Tic-Tac-Toe thực sự.


6
Vâng, điều này có thể được gọi là vũ phu buộc nó.
xem

2

Ruby, 84 ký tự

$><<(gets.tr("01","10")[r=/0..(0|.0.)..0|000(...)*$|^..0.0.0/]?:win:~r ?:lose: :cat)

Giải pháp đơn giản, dựa trên RegExp. Định dạng đầu vào là một chuỗi nhị phân gồm 9 chữ số, ví dụ 110101001cho bảng ví dụ được đưa ra trong câu hỏi.

Ruby, 78 ký tự

$><<(gets.tr("ox","xo")[r=/o...(o|.o.)...o|ooo|o_.o._o/]?:win:~r ?:lose: :cat)

Định dạng đầu vào: xxo_xox_oox


1

Haskell, 169

main=interact$(\x->last$"cat":[b|(a,b)<-[("ooo","lose"),("xxx","win")],any(==a)x]).(\x->x++(foldr(zipWith(:))(repeat[])x)++map(zipWith(!!)x)[[0..],[2,1,0]]).take 3.lines

Định dạng đầu vào: "X" chỉ được biểu thị bằng x, "O" chỉ bởi o. Trong mỗi hàng, các ký tự đồng thời không có khoảng trắng, v.v ... Hàng được phân tách bằng các dòng mới.

Tạo tất cả các hàng / cột / đường chéo có thể, sau đó lọc [("ooo","lose"),("xxx","win")]theo sự tồn tại của chúng trên bảng, sau đó chọn từ thứ hai trong tuple, để chúng tôi biết người chơi nào đã thắng. Chúng tôi trả trước "cat"để chúng tôi có thể lấy yếu tố cuối cùng của danh sách làm người chiến thắng. Nếu cả hai người chơi giành chiến thắng, "win"sẽ là người cuối cùng (danh sách hiểu được duy trì trật tự). Kể từ "cat"lúc nào cũng là lần đầu tiên, nếu một người chiến thắng tồn tại, nó sẽ được lựa chọn, nhưng nếu không một yếu tố cuối cùng vẫn tồn tại như prepending "cat"đảm bảo nonemptyness.

EDIT: Cạo 3 ký tự bằng cách thay đổi cách hiểu danh sách cuối cùng thành map.


1

C, 150 khoảng

Bây giờ là nửa đêm và tôi chưa thực hiện bất kỳ thử nghiệm nào , nhưng dù sao tôi cũng sẽ đăng khái niệm này. Tôi sẽ lấy lại vào ngày mai.

Người dùng nhập hai số bát phân (tôi muốn sử dụng nhị phân nhưng theo tôi biết C chỉ hỗ trợ bát phân):

a đại diện cho hình vuông trung tâm, 1 cho X, 0 cho O

b là một số có chín chữ số đại diện cho các ô vuông chu vi, khoanh tròn bảng bắt đầu ở một góc và hoàn thiện ở cùng một góc (chỉ lặp lại góc đó), 1 cho X, 0 cho O.

Có hai cách để chiến thắng:

  1. tâm hình vuông là X ( a= 1) và hai hình vuông đối diện cũng là X ( b&b*4096là khác không)

  2. ba hình vuông chu vi liền kề là X ( b/8 & b & b*8không khác.) Đây chỉ là một chiến thắng hợp lệ nếu hình vuông ở giữa là hình vuông cạnh, không phải hình vuông góc, do đó cũng cần phải áp dụng mặt nạ m, để tránh trường hợp hình vuông góc.

Mất được phát hiện bằng cách sử dụng biến c, là nghịch đảo của b.

int a,b,c,m=010101010;
main(){
    scanf("%o%o",a,b);c=b^0111111111;
    printf("%s",(a&&b&b*4096)|(b/8&b&b*8&m)?"win":((!a&&c&c*4096)|(c/8&c&c*8)?"lose":"cat"));
}

Bạn đã quên áp dụng mặt nạ mtrong phát hiện "mất" - c/8&c&c*8. Tôi đã đánh lại mã của bạn (không kiểm tra hoạt động của nó) như sau: int a,b;t(v){return a&&v&v<<12||v/8&v&v*8&0x208208;}main(){scanf("%o%o",a,b);printf("%s",t(b)?"win":t(b^0x1249249)?"lose":"cat");}(130 ký tự). Thử nghiệm lặp lại đủ dài để trích xuất thành chức năng thử nghiệm t(); điều này loại bỏ sự cần thiết cho cm; các hằng số được chuyển đổi thành hex để lưu một char mỗi.
Toby Speight

Chỉ cần phát hiện ra rằng printfkhông cần một chuỗi định dạng - chỉ cần cung cấp chuỗi kết quả dưới dạng định dạng - hoặc putsnó, vì câu hỏi không yêu cầu một dòng mới sau đầu ra! (tiết kiệm thêm 7 ký tự).
Toby Speight

1

Bash, 107 103

Tạo và chạy một kịch bản sed.

Định dạng I / O: oxo-oox-xoođầu ra lose(sử dụng a -để tách các hàng). Đầu vào trên stdin. Yêu cầu GNU sed cho clệnh.

Tôi đã giải thích quy tắc 5 là "nếu cả thắng và thua đều có thể, hãy chọn thắng".

Mã chính

Đây là câu trả lời thực tế.

Không có gì thú vị thực sự. Nó định nghĩa $b/cwinđể lưu các ký tự, sau đó xác định phần điều kiện thắng của tập lệnh, sau đó sử dụng sed y/x/o/\;s$b/close/để chuyển đổi xthành ocwinsang close(từ đó tạo ra các điều kiện bị mất). Sau đó, nó sẽ gửi hai thứ và ccat(sẽ xuất ra catnếu không có điều kiện thắng / thua) cho sed.

b=/cwin
v="/xxx$b
/x...x...x$b
/x..-.x.-..x$b
/x-.x.-x$b"
sed "$v
`sed y/x/o/\;s$b/close/<<<"$v"`
ccat"

Mã được tạo

Đây là tập lệnh sed được tạo và chạy bởi tập lệnh Bash.

Trong regexes, .khớp với bất kỳ ký tự nào và sau khi chúng cTEXTin văn bản và thoát ra nếu regex được khớp.

Điều này có thể chạy như một kịch bản sed độc lập. Nó dài 125 ký tự, bạn có thể coi đó là một giải pháp khác.

/xxx/cwin
/x...x...x/cwin
/x..-.x.-..x/cwin
/x-.x.-x/cwin
/ooo/close
/o...o...o/close
/o..-.o.-..o/close
/o-.o.-o/close
ccat

1

Trăn 3, 45

Đầu vào là imột danh sách các số đại diện cho mỗi hàng, cột và đường chéo của bảng trò chơi, ví dụ:

X X O
O X O
O O X

được đại diện bởi [6, 2, 1, 4, 6, 1, 7, 4].

Mã số :('cat','lose','win')[2 if 7 in i else 0 in i]


1

Phi tiêu - 119

(Xem dartlang.org ).

Phiên bản gốc sử dụng RegExp: 151 ký tự.

main(b,{w:"cat",i,p,z}){
 for(p in["olose","xwin"])
   for(i in[0,2,3,4])
     if(b[0].contains(new RegExp('${z=p[0]}(${'.'*i}$z){2}')))
       w=p.substring(1);
  print(w);
}

Đầu vào trên dòng lệnh là 11 ký tự, ví dụ: "xxx | ooo | xxx". Bất kỳ ký tự không xo có thể được sử dụng như dấu phân cách.

Khoảng trắng hàng đầu và dòng mới nên được bỏ qua trước khi đếm các ký tự, nhưng tôi cắt bỏ khoảng trắng bên trong nếu có thể. Tôi ước có một cách nhỏ hơn để tạo chuỗi con.

Phiên bản cơ sở bit recusive: 119 ký tự. Đầu vào phải là số 9 bit có 1s đại diện cho 'x' và 0 đại diện cho 'o'.

main(n){
  n=int.parse(n[0]);
  z(b,r)=>b>0?b&n==b&511?"win":z(b>>9,n&b==0?"lose":r):r;
  print(z(0x9224893c01c01e2254,"cat"));
}

1

CJam, 39 38 36 ký tự

"ᔔꉚ굌궽渒䗠脯뗠㰍㔚귇籾〳㎪䬔⹴쪳儏⃒ꈯ琉"2G#b129b:c~

Đây là mã chuyển đổi cơ sở cho

q3/_z__Wf%s4%\s4%]`:Q3'o*#"win"{Q'x3*#"lose""cat"?}?

dài 52 ký tự.

Đầu vào chỉ đơn giản là biểu diễn chuỗi của bảng bắt đầu từ trên cùng bên trái, đi từng hàng. Ví dụ:

oxooxooox

dẫn đến kết quả winđầu ra. Hoặc là

oxooxoxox

dẫn đến kết quả catđầu ra, v.v.

Mã chỉ đơn giản là thực hiện ba điều sau đây:

  • q3/_ - Chia chuỗi thành 3 phần, tức là mỗi hàng
  • _z - Sao chép mảng trên mỗi hàng và hoán chuyển thành từng mảng cột.
  • __Wf%s4%- Đảo ngược từng hàng và lấy đường chéo từ trái sang phải. Đây là đường chéo thứ cấp của bảng.
  • \s4% - Lấy đường chéo chính của bảng
  • ]` - Bọc mọi thứ trong mảng và xâu chuỗi các mảng.

Bây giờ chúng tôi có tất cả các nhóm 3 có thể từ hội đồng quản trị. Chúng tôi chỉ cần kiểm tra sự tồn tại của "ooo" và "xxx" để xác định kết quả.

Dùng thử trực tuyến tại đây


1

GNU sed, 25 byte

Nếu đầu vào là một đại diện dự phòng của bảng với các khung nhìn riêng biệt cho các cột, hàng và đường chéo, như được sử dụng trong các câu trả lời khác, thì sed rất phù hợp để kiểm tra trạng thái kết thúc của trò chơi với ít byte nhất.

Định dạng đầu vào: xxx ooo xxx xox xox xox xox xox (trạng thái bảng được lấy từ câu hỏi của OP)

/xxx/cwin
/ooo/close
ccat

Nếu định dạng đầu vào là không dự phòng ( xxx ooo xxx), thì mã sed ở trên chỉ hoạt động nếu được thêm vào bởi dòng bên dưới, làm cho chương trình dài 96 byte (với rcờ cần thiết được tính).

s/(.)(.)(.) (.)(.)(.) (.)(.)(.)/& \1\4\7 \2\5\8 \3\6\9 \1\5\9 \3\5\7/

1

Bash: 208 ký tự

y(){ tr '01' '10'<<<$@;}
f(){ x=$[($1&$2&$3)|($1&$5&$9)|($1&$4&$7)|($2&$5&$8)|($3&$5&$7)|($3&$6&$9)|($4&$5&$6)|($7&$8&$9)]; }
f $@;w=$x
f $(y $@)
([ $x -eq 1 ]&&echo lose)||([ $w -eq 1 ]&&echo win)||echo cat

Để thực thi bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Lấy cảm hứng từ câu trả lời này .


0

VB.net

Với ví dụ cung cấp được mã hóa theo mẫu bit sau

q  = &B_100101_100110_011010 ' 00 Empty, 01 = O, 10 = X

Bây giờ chúng ta có thể xác định kết quả (hoặc người chiến thắng) bằng cách làm như sau.

Dim g = {21, 1344, 86016, 66576, 16644, 4161, 65379, 4368}
Dim w = If(g.Any(Function(p)(q And p)=p),"Lose",If(g.Any(Function(p)(q And p*2)=p*2),"Win","Cat"))

0

J - 97 byte

Vâng, cách tiếp cận đơn giản nhất có sẵn. Đầu vào được lấy là 111222333, trong đó các số đại diện cho các hàng. Đọc từ trái sang phải. Người chơi là xvà kẻ thù là o. Hình vuông trống có thể là bất cứ điều gì ngoại trừ xhoặc o.

f=:(cat`lose>@{~'ooo'&c)`('win'"_)@.('xxx'&c=:+./@(r,(r|:),((r=:-:"1)(0 4 8&{,:2 4 6&{)@,))3 3&$)

Ví dụ: (NB. Là một nhận xét)

   f 'xoxxoxxox' NB. Victory from first and last column.
win
   f 'oxxxooxxx' NB. Victory from last row.
win
   f 'ooxxoxxxo' NB. The example case, lost to a diagonal.
lose
   f 'xxooxxxoo' NB. Nobody won.
cat
   f 'xoo xx ox' NB. Victory from diagonal.
win

Mã giải thích

row   =: -:"1                        Checks if victory can be achieved from any row.
col   =: -:"1 |:                     Checks if victory can be achieved from any column.
diag  =: -:"1 (0 4 8&{ ,: 2 4 6&{)@, Checks if victory can be achieved from diagonals.
check =: +./@(row,col,diag) 3 3&$    Checks all of the above and OR's them.

f     =: (cat`lose >@{~ 'ooo'&check)`('win'"_)@.('xxx'&check)
Check if you have won ........................@.('xxx'&check)
 If yes, return 'win' .............. ('win'"_)
 If not                   (cat`lose >@{~ 'ooo'&check)
  Check if enemy won ................... 'ooo'&check
   If yes, return 'lose'   ---`lose >@{~
   If not, return 'cat'    cat`---- >@{~

0

Python 2, 120 byte

b=0b101001110
l=[448,56,7,292,146,73,273,84]
print(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

Hoặc Python, 115 byte từ trình bao Python (2 hoặc 3):

b=0b101001110;l=[448,56,7,292,146,73,273,84];(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

Biến bảng được đặt thành định dạng nhị phân được mô tả trong câu hỏi: 1cho X, 0cho O, từ trái sang phải, từ trên xuống dưới. Trong trường hợp này, 101001110đại diện

XOX
OOX
XXO

Dẫn đến đầu ra: Cat


Định dạng đầu vào là gì?
xem

0

Con trăn ( 73 62 ký tự)

Đầu vào là bốn chuỗi chữ thường đại diện cho bốn khung nhìn riêng biệt của cùng một bảng, tất cả được nối thành một chuỗi duy nhất: theo hàng, theo cột, đường chéo phải, đường chéo trái.

CẬP NHẬT

Cảm ơn theRare đã chỉ ra điều này với một ví dụ phản biện tốt! Mỗi chế độ xem bảng, cùng với mỗi phân đoạn (hàng hoặc cột) trong bảng phải được phân tách bằng ký tự không phải là "x" hoặc "o" để cấu trúc của bảng được bảo tồn ngay cả sau khi ghép. Các đường viền xung quanh mỗi khung nhìn của bảng sẽ là dấu ngoặc vuông ("[" và "]") và dấu phân cách giữa các hàng / cột sẽ là ký tự ống "|".

Điều này làm cho thuật toán trở nên đơn giản - chỉ cần tìm "xxx" hoặc "ooo" để giành chiến thắng hoặc thua, tương ứng. Nếu không thì đó là cà vạt (mèo).

Ví dụ: bảng (đọc từ trái sang phải, từ trên xuống dưới) ...

X | X | X X | O | X O | X | O

... được biểu diễn dưới dạng "[xxx | xox | oxo]" (theo hàng) + "[xxo | xox | xxo]" (theo cột) + "[xoo]" (phải diag) + [xoo] "(bên trái diag) = "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]".

Câu lệnh Python này in kết quả trò chơi với biến s là đầu vào:

print 'win' if 'xxx' in s else 'lose' if 'ooo' in s else 'cat'

Điều này có làm việc cho hội đồng quản trị OXX XOO XOX(nó nên là con mèo)?
xem

Không ... không, không. Nắm bắt tốt! Tôi đoán giải pháp của tôi quá đơn giản ... Rất tiếc!
bob

Tôi không thể nói loại giải pháp này không vượt qua tâm trí của tôi. :)
xem

0

Haskell (69 ký tự)

i x=take 4$(x>>=(\y->case y of{'7'->"win";'0'->"lose";_->""}))++"cat"

Điều này có cùng đầu vào như được mô tả bởi câu trả lời này . Cụ thể hơn, đầu vào là 8 giá trị bát phân, mô tả giá trị nhị phân của mỗi hàng, cột và đường chéo. Mã này làm cho mọi trường hợp của 7 "thắng", mọi trường hợp 0 ​​"thua" và loại bỏ mọi thứ khác. Sau đó, nó thêm "con mèo" vào cuối và lấy 4 ký tự đầu tiên từ kết quả.

Sẽ có 4 câu trả lời khả thi: "thua", "mèo", "thắng" theo sau là 'l' và "thắng" theo sau là 'c', điều mà các quy tắc không cấm :)

Ví dụ sử dụng:

i "65153806" --outputs "lose"

0

J: 83

(;:'lose cat win'){::~>:*(-&(+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))-.)3 3$'x'=

Cách sử dụng: chỉ cần nối thêm một chuỗi x và o và xem tác phẩm kỳ diệu. ví dụ. 'xxxoooxxx'.

Động từ bên trong (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))về cơ bản kết hợp các ma trận nhị phân ban đầu, với chuyển vị được đóng hộp cùng với 2 đường chéo. Những kết quả này được san bằng với nhau; tổng hàng được thực hiện để xác định chiến thắng, và sau đó tổng hợp. hơn nữa tôi sẽ gọi động từ nàyInner .

Để tìm ra người chiến thắng, sự khác biệt về điểm số giữa các ma trận nhị phân bình thường và nghịch đảo được lấy bằng móc (-&Inner -.).

Phần còn lại của mã chỉ đơn giản là tạo đầu ra và chọn đúng.


0

JavaScript, 133 , 114 ký tự

r = '/(1){3}|(1.{3}){2}1|(1.{4}){2}1|(1\|.1.\|1)/';alert(i.match(r)?'WIN':i.match(r.replace(/1/g,0))?'LOSS':'CAT')

Đầu vào ilà một chuỗi đơn giản với các dấu phân cách cho các hàng, nghĩa là100|001|100

Chỉnh sửa: đã cập nhật phương pháp của tôi để thay thế 1s trong regex bằng 0 để kiểm tra trường hợp mất.


Bạn có thể loại bỏ khoảng trắng xung quanh =và dấu ngoặc kép quanh chữ regex. Ngoài ra, 1...là một ký tự ngắn hơn 1.{3}.
nyuszika7h

1
r.test(i)cũng là một ký tự ngắn hơn i.match(r).
nyuszika7h

0

J - 56 (26?)

Đầu vào được đưa ra một ma trận 3x3 gồm chín ký tự, bởi vì J có thể hỗ trợ đó là một kiểu dữ liệu, LOL.

(win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)

Ví dụ:

   NB. 4 equivalent ways to input the example board
   (3 3 $ 'xxoxoxoox') ; (_3 ]\ 'xxoxoxoox') ; ('xxo','xox',:'oox') ; (];._1 '|xxo|xox|oox')
+---+---+---+---+
|xxo|xxo|xxo|xxo|
|xox|xox|xox|xox|
|oox|oox|oox|oox|
+---+---+---+---+
   (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.) 3 3 $ 'xxoxoxoox'
lose
   wlc =: (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)
   wlc (3 3 $ 'xoxoxooxo')
cat
   wlc (3 3 $ 'xxxoooxxx')
win

Nếu chúng ta được phép mã hóa Golfscriptish các chữ số bát phân đại diện cho trạng thái của từng hàng, cột và đường chéo, thì đó chỉ là 26 ký tự:

   win`lose`cat{::~7 0<./@i.] 6 5 1 6 4 3 5 0
lose
   f=:win`lose`cat{::~7 0<./@i.]
   f  7 0 7 5 5 5 5 5
win

0

T-SQL (2012), 110

select max(iif(@&m=0,'lose',iif(@&m=m,'win','cat')))from(VALUES(292),(146),(73),(448),(56),(7),(273),(84))z(m)

Đầu vào là một số hex. Đây là bản dịch của giải pháp ruby ​​thành T-SQL khá đẹp và gọn gàng.


0

Javascript 1.6, 71 ký tự

Tôi giả sử đầu vào là một mảng gamechứa mỗi hàng, mỗi cột và mỗi diag là một chuỗi 3 char. Tương tự như câu trả lời của bob , nhưng nó có trong một mảng, không phải là một chuỗi nối.

alert(game.indexOf("xxx")>=0?"win":game.indexOf("ooo")>=0?"lose":"cat")

Nhận xét của EDIT @ nyuszika7h (67 ký tự)

alert(~game.indexOf("xxx")?"win":~game.indexOf("ooo")?"lose":"cat")

Bạn có thể sử dụng ~game.indexOf("xxx")thay vì game.indexOf("xxx")>=0, tương tự cho người khác.
nyuszika7h

0

Java 7, 260 byte

String c(int[]s){int a[]=new int[8],x=0,y;for(;x<3;x++){for(y=0;y<3;a[x]+=s[x*3+y++]);for(y=0;y<3;a[x+3]+=s[y++%3]);}for(x=0;x<9;y=s[x],a[6]+=x%4<1?y:0;a[7]+=x%2<1&x>0&x++<8?y:0);x=0;for(int i:a)if(i>2)return"win";for(int i:a)if(i<1)return"loose";return"cat";}

Các trường hợp bất ngờ & thử nghiệm:

Hãy thử nó ở đây.

class M{
  static String c(int[] s){
    int a[] = new int[8],
        x = 0,
        y;
    for(; x < 3; x++){
      for(y = 0; y < 3; a[x] += s[x * 3 + y++]);
      for (y = 0; y < 3; a[x + 3] += s[y++ % 3]);
    }
    for(x = 0; x < 9; y = s[x],
                      a[6] += x % 4 < 1
                               ? y
                               : 0,
                      a[7] += x % 2 < 1 & x > 0 & x++ < 8
                               ? y
                               : 0);
    x = 0;
    for(int i : a){
      if(i > 2){
        return "win";
      }
    }
    for(int i : a){
      if(i < 1){
        return "loose";
      }
    }
    return "cat";
  }

  public static void main(String[] a){
    /*  xxo
        xox
        oox  */
    System.out.println(c(new int[]{ 1, 1, 0, 1, 0, 1, 0, 0, 1 }));
    /*  xxx
        ooo
        xxx  */
    System.out.println(c(new int[]{ 1, 1, 1, 0, 0, 0, 1, 1, 1 }));
    /*  xxo
        oox
        xox  */
    System.out.println(c(new int[]{ 1, 1, 0, 0, 0, 1, 1, 0, 1 }));
  }
}

Đầu ra:

loose
win
cat

0

APL (NARS), 69 ký tự, 138 byte

{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}

Đầu vào phải là một ma trận 3x3 hoặc một mảng tuyến tính gồm 9 phần tử chỉ có thể là 1 (đối với X) và 0 (đối với O), kết quả sẽ là "con mèo" nếu không ai thắng, "thua" nếu O thắng, "thắng "Nếu X thắng. Không có kiểm tra cho một bảng không hợp lệ hoặc đầu vào là một mảng có ít hơn 9 phần tử trở lên hoặc kiểm tra từng phần tử <2.

Như một nhận xét: nó sẽ chuyển đổi đầu vào trong ma trận 3x3 và xây dựng một mảng có tên "x" trong đó các phần tử là tổng của mỗi cột hàng và đường chéo.

Một số thử nghiệm xem ví dụ cho thấy từ những người khác:

  f←{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}
  f 1 2 3
win
  f 0 0 0
lose
  f 1 0 1  1 0 1  1 0 1
win
  f 0 1 1  1 0 0  1 1 1
win
  f 0 0 1  1 0 1  1 1 0
lose
  f 1 1 0  0 1 1  1 0 0
cat
  f 1 1 0  0 1 0  0 0 1
win
  f 1 1 0  1 0 1  0 0 1
lose
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.