Визначте виграш у Tictactoe


19

Давайте пограємо в гольф коду!

Дано стан дошки з тик-носом (Приклад :)

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

Визначте, чи гра є wina loseчи cat. Ваш код повинен виводити будь-який із цих параметрів із заданим станом. Вищеописана гра повинна вивестиlose

Просто, щоб було зрозуміло: виграш визначається як будь-які 3 xс підряд (діагональний, горизонтальний, вертикальний). програш - 3 oсек поспіль, а catгра в жодному підряд.

Щоб зробити цікаві речі, ви маєте визначити свою структуру вводу для стану, який ви повинні пояснити. Наприклад xxoxoxoox, допустимий стан, як видно вище, де кожен з символів читається зліва направо, зверху вниз. [['x','x','o'],['x','o','x'],['o','o','x']]це гра в багатовимірний масив, що читається аналогічно. Хоча, 0x1a9який є шістнадцятковим, 110101001може працювати як придатне стиснення, де 1можна маніпулювати для xs, а за ним 0можна маніпулювати o.

Але це лише деякі ідеї, я впевнений, що у вас може бути багато власних.

Основні правила:

  1. Ваша програма повинна вміти приймати будь-який життєздатний стан.
  2. Форма введення повинна вміти представляти будь-який стан.
  3. "Стан виграшу повинен визначатися з дошки"
  4. Припустимо повну дошку
  5. Winперед, loseнаприклад, у справі "xxxoooxxx"

Виграє найменший кількість персонажів


1
Мені подобається така структура вводу:, (win|lose|cat) [xo]{9}де перше слово позначає, чи гра є виграш, програш чи кіт (?) Для гравця x. Здатний представляти будь-яку державу.
Runer112

2
Чи можу я запропонувати правило на кшталт "Стан виграшу повинен визначатися на платі" або "Вхід не повинен містити жодної інформації, крім стану плати"?
підземниймонорельс

3
Ми припускаємо, що грають лише легальні ігри? Якщо так, певні стани були б неможливі, тобто XXX OOO XXX, але в іншому випадку деякі штатні повноцінні стани включають це як четвертий неможливий результат, де X перемагає, але O також виграє.
Бунт

10
чому "котик" з інтересу?
Кріс

7
@DylanMadisetti: ніколи не чув про це раніше, і googlign для "win lose cat" не придумав нічого. Я б пішов з краваткою або малював особисто. Або у випадку з цією грою може бути "неминучість". ;-) Я не дуже заперечую щодо конкуренції. Рядок - це рядок. ;-)
Кріс,

Відповіді:


11

Ruby 2.0, 85 символів

Ось просте рішення на основі біткої маски в Ruby:

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

Дошка представлена ​​у вигляді шістнадцяткового числа, що складається з дев'яти біт, що відповідають дев’яти квадратам. 1 - an X, 0 - an O. Це так само, як 0x1a9приклад у питанні, хоча 0xопція є необов’язковою!

Можливо, є кращий спосіб зробити бітмаски, а потім просто жорстке кодування великого списку. Я із задоволенням прийму пропозиції.

Дивіться, як він працює на Ideone тут .


1
Ваш список містить 273двічі. І мені дуже подобається maxідея!
Вентеро

1
О @ Вентеро, завжди з незрозумілими оптимізаціями (спасибі)
Пол Престиджеж

На дошці можуть бути порожні місця. Ваш формат введення не враховує цього, тому не може представляти жодного життєздатного стану гри.
Стівен Остерміллер

2
@StephenOstermiller правило 4: візьміть на себе повну дошку. Ви впевнені, що це правило, можливо, суперечить правилам 1 і 2, однак, якщо ви читаєте всі коментарі до цього питання, я думаю, що це відповідає духу питання (неповні дошки не охоплені, а повні, але незаконні дошки). Однак я думаю, що восьмигранник буде більш зручним для введення форматом введення, ніж шістнадцятковий.
Рівень річки Св.

1
Зрозумів, я вважав, що завершене означає щось інше.
Стівен Остерміллер

10

Математика, 84 ч

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

Формат введення: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}


Що тут відбувається?
seequ

3
@TheRare Почніть праворуч. Tr@aє слід поля (сума по діагоналі), Tr@Reverse@aє слід перевернутого поля (деякі більш анти-діагональ), Tr/@aбуде Trзастосовуватися до кожного рядка, яка дає вам суму по кожному рядку, Total@aдає вам суму по кожному стовпчику. Отже, у вас є всі 8 рядків, які вам потрібно перевірити. Тоді Whichріч застосовується до цього (в основному if/elseif/elseтвердження), де #представлений цей список із 8 значень. ifє 3виграш, else ifє 0програш, else if 1>0(правда) cat.
Мартін Ендер

6

Баш: 283 262 258

Завдяки відносно дружньому інтерфейсу

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

Для виконання bash tictactoe.sh O X O X O X X O X

Примітка: список 9 позицій - це стандартне матричне подання. Не має значення, чи дошка представлена ​​як основна стовпець чи велика рядок, читання зліва направо чи зверху вниз - ігри на нулетах та хрестиках (або тик-носок, якщо ви наполягаєте) є симетричними, тому порядок введення повинен бути нерелевантним. до результату в кожній правильній реалізації, якщо введення лінійне.

Редагувати: Завдяки hjk для коротшої пропозиції синтаксису функції.


Розглянемо t() { ... }замість function t? Можна зберегти там кілька символів. :)
hjk

Я повністю забув про синтаксис альтернативної функції - дякую!
Бунт

Пробіли не потрібні навколо, <<<щоб зберегти ще чотири символи.
Майкл Міор

4

Befunge 93 - 375

Приймає двійковий рядок як вхідний.

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       <^  <

Читає рядок. Bruteforce записує це (найправіша вертикальна смужка) як матрицю між

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

додавання решітки (idk). Визначає суму стовпців, рядків та двох діагнозів. Порівняє ці значення з 3 ("виграти") або 0 ("програти"), інакше, якщо всі значення рівні 1 або 2, тоді буде намальовано ("кішка").


4

GolfScript, 27 символів

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

Формат введення - це рядок, що складається з восьми восьмеричних цифр, кожна (що надлишково) кодує три послідовних квадратики:

  • Перші три цифри кодують кожен ряд дошки зверху вниз та зліва направо.
  • Наступні три цифри кодують кожну колонку дошки, зліва направо і зверху вниз.
  • Останні дві цифри кодують кожну з діагоналей (спочатку зверху ліворуч праворуч знизу, потім знизу зліва вгору праворуч).

Щоб кодувати послідовність (рядок / стовпчик / діагональ) з трьох квадратів у вигляді восьмеричної цифри, замініть кожен xу послідовності на 1, а кожен oна 0, і інтерпретуйте отриману послідовність одиниць і нулів як двійкове число між 0 і 7 включно.

Цей формат введення досить зайвий (всі позиції дощок кодуються щонайменше в два раз, з центральним положення кодувати чотири рази), але це однозначно представляти будь-яке можливе стан повністю заповнений хрестики-нулики борту, а не безпосередньо кодувати переможець у вхід.

Введення може, за бажанням, містити пробіли та інші роздільники між цифрами. Насправді вся програма, яка насправді піклується, полягає в тому, містить чи вхідний рядок цифри 7чи ні 0.

Наприклад, дошка прикладу:

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

може бути представлений вхідними даними:

651 643 50

Для зручності ось програма GolfScript для перетворення макета плати мистецтв ASCII, як показано в виклику вище, у рядок введення, що підходить для цієї програми:

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

Цей перетворювач ігнорує будь-які символи, окрім xі o, в будь-якому випадку, у своєму введенні. Він створює одноцифровий рядок (у комплекті з роздільниками пробілу, як показано вище), що підходить для подачі у програму, що визначає виграш вище, тому з'єднання цих двох програм може бути використане для визначення переможця безпосередньо з арт-дошки ASCII.

Крім того, ось зворотний перетворювач, щоб просто продемонструвати, що вхід дійсно однозначно представляє плату:

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

Пс. Ось онлайн демонстрація цього рішення.


2
Формат введення, здається, є чистим читком, оскільки значна частина роботи відбувається у виробництві введення.
Арку

@Arkku: Так, так, але в питанні прямо сказано, що "ви маєте визначити свою структуру входу для держави - яку ви повинні потім пояснити". Він навіть показує розфасовану шістнадцяткову рядок як приклад допустимого вхідного формату; Єдина відмінність цього формату від мого вхідного формату полягає в тому, що я переупорядковую і копіюю деякі біти.
Ільмарі Каронен

6
Саме дублювання здається читком. (Наприклад, це робить безпосередньо кодувати переможця , як наявність 7 або 0 на вході)
Arkku

Все-таки це розумне кодування, воно зайве, але робить пошук рішення набагато ефективнішим, ніж будь-яке не надмірне кодування!
ARRG

3

Python 2 - 214 байт

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'

Я впевнений, що слід вдосконалити.

Бігти:

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

яка представляє цю дошку:

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

Виходить за NameErrorвинятком у всіх випадках, крім cat.


О, я ніколи про це не знав <<<! +1 просто для цього.
Грег Хьюгілл

@GregHewgill Це досить зручно. ./whatever <<< 'blah blah blah'це те саме, echo -n 'blah blah blah' | ./whateverале без цілого окремого процесу для echo.
підземниймонорельс

@undergroundmonorail echoв bashнасправді є вбудованим, тому не розгортає нового процесу
Боб

@GregHewgill це називається єрестинг

3

Haskell, 146 символів

Щоб зробити цікаві речі, ви маєте визначити свою структуру вводу для стану, який ви повинні пояснити.

ДОБРЕ :). Моє представлення дошки - один з цих 126 символів

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

Ось рішення в 146 символів:

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

Ось як це працює, як сценарій 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 символів

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'

У цій версії sміститься ціле число, яке представляє стан ігрової дошки. Це невеликий масив значення, де два біти представляють кожен квадрат на дошці:

  • 10 - X
  • 11 - О
  • 00 - Порожній квадрат

Це рішення використовує біт-маніпуляцію для тестування кожної з восьми можливих конфігурацій "три підряд" (вона тестує їх двічі, один раз для X і один раз для O).

Я представляю це з незначним зменшенням з мого веб-сайту Tic-Tac-Toe, де ця detectWinфункція використовується як частина справжньої гри Tic-Tac-Toe.


6
Ну, це можна назвати грубим примушуванням.
seequ

2

Рубі, 84 символи

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

Просте, на основі RegExp рішення. Формат введення - це 9 -значний двійковий рядок, наприклад 110101001для прикладу дошки, наведеної у питанні.

Рубі, 78 символів

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

Формат введення: xxo_xox_oox


1

Хаскелл, 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

Формат вводу: "X" представлений лише x"," лише ""o . У кожному рядку символи є одночасними без пробілів тощо. Рядки розділені новими рядками.

Створює всі можливі рядки / стовпці / діагоналі, потім фільтрує [("ooo","lose"),("xxx","win")]їх існування на дошці, потім вибирає друге слово в кортежі, щоб ми знали, які гравці перемогли. Ми готуємося, "cat"щоб ми могли взяти останній елемент списку як наш переможець. Якщо обидва гравці виграли, "win"вони будуть останніми (список розумінь підтримує порядок). Оскільки "cat"завжди є першим, якщо переможець існує, він буде обраний, але в іншому випадку останній елемент все ще існує як попередній"cat" гарантує непорожнечу.

EDIT: Поголений 3 символи, змінивши розуміння останнього списку на map.


1

C, 150 прибл

Тут півночі, і я не робив жодного тестування , але я все-таки опублікую цю концепцію. Я повернусь до цього завтра.

Користувач вводить два восьмі числа (я хотів використовувати двійкові, але наскільки я знаю, C підтримує лише восьмеричні):

a являє собою центральний квадрат, 1 для X, 0 для O

b - дев'ятицифрове число, що представляє квадрати периметра, кружляють навколо дошки, починаючи з одного кута і закінчуючи в тому ж куті (тільки з повторенням цього кута), 1 для X, 0 для O.

Є два можливі способи виграти:

  1. центральна площа X ( a= 1), а два протилежні квадрати також X ( b&b*4096є ненульовим)

  2. три сусідні квадрати периметра - це X ( b/8 & b & b*8є ненульовим.) Це справедливий виграш, якщо середній квадрат - це край ребра, а не кутовий квадрат, тому слід також застосувати маску m, щоб уникнути випадків кутового квадрата.

Втрата виявляється за допомогою змінної c, яка є оберненою 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"));
}

Ви забули застосувати маску mпри виявленні "програш" - c/8&c&c*8. Я перезавантажив ваш код (не перевіряючи його роботу) наступним чином: 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 символів). Повторне випробування було достатньо довгим, щоб вийти на тестову функцію t(); це знімає потребу в cі m; константи, перетворені в шістнадцяткову, щоб зберегти по одній картці кожен.
Toby Speight

Щойно помітив, що printfне потрібна рядка формату - просто надайте рядок результатів як формат - або putsце, оскільки питання не вимагає нового рядка після виходу! (економить ще 7 символів).
Toby Speight

1

Bash, 107 103

Створює та запускає сценарій sed.

Формат вводу / виводу: oxo-oox-xooвиводи lose(використовуйте a -для розділення рядків). Введення на stdin. Потрібна GNU sed дляc команди .

Я трактував правило 5 як "якщо можливі і перемога, і програш, вибирай виграш".

Основний кодекс

Це фактична відповідь.

Нічого цікавого насправді. Він визначає $bяк /cwinзбереження символів, потім визначає умову виграшу частини сценарію, потім використовує sed y/x/o/\;s$b/close/для перетворення xв oта cwinдо close(тим самим генеруючи умови втрати). Потім він відправляє дві речі і ccat(які виводяться, catякщо не вирівняється умова виграш / програш) на 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"

Створений код

Це сценарій sed, створений та запущений сценарієм Bash.

У реджексах .відповідає будь-який символ і після них cTEXTнадрукується TEXT і виходить, якщо регулярний вирівнювання збігається.

Це може працювати як окремий сценарій sed. Це 125 символів, ви можете вважати це ще одним рішенням.

/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

Пітон 3, 45

Вхід є i, тобто список номерів, що представляють кожен рядок, стовпець та діагональ ігрової дошки, наприклад:

X X O
O X O
O O X

представлена [6, 2, 1, 4, 6, 1, 7, 4].

Код :('cat','lose','win')[2 if 7 in i else 0 in i]


1

Дартс - 119

(Див. Dartlang.org ).

Оригінальна версія за допомогою RegExp: 151 символів.

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);
}

Введіть у командному рядку 11 символів, наприклад, "xxx | ooo | xxx". Будь-який символ не xo може використовуватися як роздільник.

Перед підрахунком символів слід опустити провідні пробіли та нові рядки, але я вирізав внутрішній пробіл, де це можливо. Я хотів би, щоб був менший спосіб зробити підрядку.

Репресивна бітова база: 119 символів. Вхід повинен бути 9-бітним числом з 1, що представляє "x", а 0s - "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 символів

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

Це базовий перетворений код для

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

який становить 52 символи.

Вхід - це просто рядкове представлення дошки, починаючи з верхнього лівого кута, йдучи рядок за рядком. Наприклад:

oxooxooox

що призводить до winвиходу. Або

oxooxoxox

що призводить до catвиходу тощо.

Код просто робить такі три речі:

  • q3/_ - Розбийте рядок на 3 частини, тобто на ряд
  • _z - Скопіюйте масив на рядок та перемістіть у масив на кожен стовпець.
  • __Wf%s4%- Переверніть кожен ряд і дістаньте діагоналі зліва направо. Це вторинна діагональ дошки.
  • \s4% - Отримайте головну діагональ дошки
  • ]` - Оберніть все в масив і оберіть масив.

Тепер у нас є всі можливі групи по 3 з дошки. Ми просто перевіряємо наявність "ooo" і "xxx", щоб визначити результат.

Спробуйте його онлайн тут


1

GNU sed, 25 байт

Якщо вхід представляє собою надмірне представлення дошки з окремими видами для стовпців, рядків та діагоналей, як це використовується і в інших відповідях, то sed дуже добре підходить для перевірки кінцевого стану гри з найменшими байтами.

Формат введення: xxx ooo xxx xox xox xox xox xox (стан ради взято з питання про ОП)

/xxx/cwin
/ooo/close
ccat

Якщо формат введення не надлишковий ( xxx ooo xxx), код Sed працює вище, лише якщо він передбачений рядком нижче, роблячи програму довжиною 96 байт (з rврахуванням необхідного прапора).

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

1

Баш: 208 символів

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

Для виконання bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Натхненний цією відповіддю .


0

VB.net

З прикладом подання кодується як наступний біт-шаблон

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

Тепер ми можемо визначити результат (або переможець), виконавши наступне.

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 байт

Ну, найпростіший підхід. Вхід приймається як 111222333, де числа представляють рядки. Читайте зліва направо. Гравець є, xа ворог - це o. Порожні квадрати можуть бути будь-якими, крім xабо o.

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

Приклади: (NB. Це коментар)

   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

Ungolfed код пояснення

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 байт

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]

Або Python, 115 байт з оболонки Python (2 або 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]

Змінна плата встановлюється у двійковому форматі, описаному у запитанні: 1для X, 0для O, зліва направо, зверху вниз. У цьому випадку 101001110представляє

XOX
OOX
XXO

Що призводить до виходу: Cat


Який формат введення?
seequ

0

Пітон ( 73 62 символи)

Вхід - це чотири рядки з малого регістру, що представляють чотири різних виду однієї дошки, всі об'єднані в один рядок: за рядком, стовпцем, правою діагоналлю, лівою діагоналлю.

ОНОВЛЕННЯ

Дякуємо theRare за те, що вказали це на хорошому зустрічному прикладі! Кожен вигляд дошки, разом з кожним сегментом (рядком або стовпцем) всередині дошки, повинен бути відокремлений символом, який не є ні «х», ні «о», щоб структура дошки зберігалася навіть після конкатенації. Межі навколо кожного подання дошки будуть квадратними дужками ("[" і "]"), а роздільник між рядками / стовпцями буде символом "" ".

Це робить алгоритм простим - просто шукайте "xxx" або "ooo" на виграш або програш відповідно. Інакше це краватка (кіт).

Наприклад, дошка (читання зліва направо, зверху вниз) ...

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

... представляється як "[xxx | xox | oxo]" (за рядками) + "[xxo | xox | xxo]" (за стовпцями) + "[xoo]" (правий діагноз) + [xoo] "(зліва diag) = "[xxx | xox | оксо] [xxo | xox | xxo] [xoo] [xoo]".

Цей оператор Python друкує результат гри, даючи змінну s як вхідний:

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

Чи працює ця дошка OXX XOO XOX(це повинна бути кішка)?
seequ

Ні ... ні, ні. Гарний улов! Я думаю, моє рішення було занадто простим ... На жаль!
боб

Я не можу сказати, що такий тип рішення не надумав. :)
seequ

0

Haskell (69 символів)

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

Це займає той самий вхід, як описано в цій відповіді . Більш конкретно, вхід - 8 восьми значень, що описують двійкове значення кожного рядка, стовпця та діагоналі. Код робить кожен екземпляр 7 "win", кожен екземпляр 0 "програє", а все інше видаляє. Потім він додає "кішку" до кінця і забирає перші 4 символи від результату.

Існує 4 можливі відповіді: "програти", "кішка", "перемогти", а потім "l", і "win", а потім "c", які правила не забороняють :)

Приклад використання:

i "65153806" --outputs "lose"

0

J: 83

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

Використання: просто додайте рядок з x і o і перегляньте магічну роботу. напр. 'xxxoooxxx'.

Внутрішнє дієслово, в (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))основному, поєднує в собі оригінальну двійкову матрицю, а переносну коробку разом з двома діагоналями Ці результати зрізані між собою; рядкові суми беруться для визначення виграшів, а потім підсумовуються. далі я назву це дієслово Inner.

Для пошуку переможця різницю балів між нормальною та перевернутою двійковими матрицями приймається гачком (-&Inner -.) .

Решта коду просто робить виходи та вибирає правильний.


0

JavaScript, 133 , 114 символів

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

Вхід i- це проста рядок з роздільниками для рядків, тобто100|001|100

Редагувати: оновив мій метод заміни нулів у регулярному вираженні нулями, щоб перевірити наявність випадку втрат.


Ви можете видалити пробіли навколо =і лапки навколо прямокутника. Також на 1...один символ коротший 1.{3}.
nyuszika7h

1
r.test(i)також на один символ коротший i.match(r).
nyuszika7h

0

J - 56 (26?) Знаків

Для введення дана матриця 3x3 з дев'яти символів, оскільки J може підтримувати це як тип даних, LOL.

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

Приклади:

   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

Якщо нам дозволено кодування голфскриптів восьмеричних цифр, що надмірно відображають стан кожного рядка, стовпця та діагоналі, то це всього 26 символів:

   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)

Введення - це шістнадцяткове число. Це в значній мірі переклад рубінового рішення на T-SQL досить приємний і акуратний.


0

Javascript 1.6, 71 символів

Я припускаю, що введення є масивом, gameякий містить кожен рядок, кожен стовпець та кожен діагноз у вигляді 3-х рядкових рядків. Схожий на відповідь bob , але він надходить у масив, а не як з'єднаний рядок.

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

EDIT @ nyuszika7h коментар «s (67 символів)

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

Ви можете використовувати ~game.indexOf("xxx")замість того game.indexOf("xxx")>=0ж, для іншого.
nyuszika7h

0

Java 7, 260 байт

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";}

Невикористані та тестові справи:

Спробуйте тут.

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 }));
  }
}

Вихід:

loose
win
cat

0

APL (NARS), 69 символів, 138 байт

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

Вхід повинен бути однією матрицею 3x3 або одним лінійним масивом з 9 елементів, який може бути лише 1 (для X) і 0 (для O), результат буде "cat", якщо ніхто не виграє, "програють", якщо O виграє, "win "якщо X переможе. Немає перевірки на одну недійсну дошку або вхід - один масив містить менше 9 елементів або більше або перевіряє кожен елемент <2.

Як коментар: вона перетворила б вхід в матрицю 3x3 і побудувала один масив з назвою "x", де елементами є сума кожного стовпця рядків та діагоналі.

Деякі приклади тестування див. З інших:

  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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.