Determinar a vitória no Tictactoe

19

Vamos jogar um código de golfe!

Dado o estado da placa do jogo da velha (exemplo :)

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

Determine se um jogo é um wina loseou cat. Seu código deve gerar uma dessas opções, dependendo do estado. O jogo acima deve gerarlose

Só para esclarecer: uma vitória é definida como qualquer 3 xs consecutivos (diagonal, horizontal, vertical). uma perda é de 3 os seguidos, enquanto um catjogo não é seguido.

Para tornar as coisas interessantes, você determina sua estrutura de entrada para o estado - que você deve explicar. Por exemplo, xxoxoxooxé um estado válido, como visto acima, onde cada um dos caracteres é lido da esquerda para a direita, de cima para baixo. [['x','x','o'],['x','o','x'],['o','o','x']]é o jogo em matriz multidimensional lido de maneira semelhante. Enquanto 0x1a9que é hexagonal para 110101001trabalho poder como uma compressão apropriada, onde 1pode ser manipulado para xs e 0pode ser manipulado para o.

Mas essas são apenas algumas idéias, tenho certeza que você pode ter muitas.

Regras básicas:

  1. Seu programa deve poder aceitar qualquer estado viável.
  2. A forma de entrada deve ser capaz de representar qualquer estado.
  3. "O estado da vitória deve ser determinado a partir do quadro"
  4. Suponha uma placa completa
  5. Winantes, losepor exemplo, no caso 'xxxoooxxx'

Vitórias mais baixas na contagem de caracteres

Dylan Madisetti
fonte
11
Gosto dessa estrutura de entrada:, (win|lose|cat) [xo]{9}onde a primeira palavra indica se o jogo é uma vitória, uma derrota ou um gato (?) Para o jogador x. Capaz de representar qualquer estado.
Runer112
2
Posso sugerir uma regra como "O estado da vitória deve ser determinado pelo quadro" ou "A entrada não deve conter informações, exceto o estado do quadro"?
undergroundmonorail
3
Estamos assumindo que apenas jogos legais são jogados? Nesse caso, alguns estados seriam impossíveis, ou seja, XXX OOO XXX, mas, caso contrário, alguns estados de pensão completa incluem isso como um quarto resultado impossível, onde X vence, mas O também vence.
Motim
10
por que "gato" por interesse?
22414 Chris
7
@DylanMadisetti: nunca ouvi isso antes e o googlign de "win perde gato" não deu em nada. Eu teria usado gravata ou desenho pessoalmente. Ou, no caso deste jogo, talvez "inevitabilidade". ;-) Não me importo muito com a competição. Uma string é uma string. ;-) #
284

Respostas:

11

Ruby 2.0, 85 caracteres

Aqui está uma solução simples baseada em máscara de bit no Ruby:

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

A placa é representada como um número hexadecimal, composto por nove bits correspondentes aos nove quadrados. 1 é um X, 0 é um O. É exatamente como o 0x1a9exemplo da pergunta, embora o 0xseja opcional!

Provavelmente existe uma maneira melhor de fazer as máscaras de bits do que apenas codificar uma grande lista. Ficarei feliz em receber sugestões.

Veja-o rodando no Ideone aqui .

Paul Prestidge
fonte
11
Sua lista contém 273duas vezes. E eu realmente gosto da maxideia!
Ventero
11
Oh @Ventero, sempre com as otimizações obscuros (graças)
Paul Prestidge
Pode haver espaços vazios em um quadro. Seu formato de entrada não explica isso e, portanto, não pode representar nenhum estado de jogo viável.
Stephen Ostermiller
2
@StephenOstermiller regra 4: assuma uma prancha completa. Você está certo de que esta regra talvez seja contrariada pelas regras 1 e 2; no entanto, se você ler todos os comentários sobre a pergunta, acho que isso está dentro do espírito da pergunta (painéis incompletos não são cobertos, enquanto painéis completos, mas ilegais). No entanto, acho que o octal seria um formato de entrada mais amigável que o hex.
Nível do rio St
11
Entendi, pensei que completo significava algo diferente.
Stephen Ostermiller
10

Mathematica, 84 caracteres

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

Formato de entrada: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}

alefalpha
fonte
O que está acontecendo aqui?
seequ
3
@TheRare Comece da direita. Tr@aé o rastreamento do campo (soma acima da diagonal), Tr@Reverse@aé o rastreamento do campo invertido (alguns acima da anti-diagonal), Tr/@aé Traplicado a cada linha, que fornece a soma de cada linha, Total@afornece a soma de cada coluna. Então, basicamente, você tem todas as 8 linhas que precisa verificar. Então, a Whichcoisa é aplicada a isso (basicamente uma if/elseif/elsedeclaração), onde #representa essa lista de 8 valores. ifhá um que 3você ganha, else ifhá um que 0você perde else if 1>0(verdade) cat.
Martin Ender
6

Bash: 283 262 258

Apresentando uma interface relativamente amigável.

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

Executar bash tictactoe.sh O X O X O X X O X

Nota: a lista de 9 posições é uma representação matricial padrão. Não importa se o quadro é representado como coluna maior ou linha maior, lido da esquerda para a direita ou de cima para baixo - jogos de zeros e cruzamentos (ou tic tac toe se você insistir) são simétricos, portanto, a ordem de entrada deve ser irrelevante para o resultado em toda implementação correta, desde que a entrada seja linear.

Edit: Obrigado ao hjk pela sugestão de sintaxe de função mais curta.

Tumulto
fonte
Considere em t() { ... }vez de function t? Pode salvar alguns caracteres lá. :)
HJK
Eu tinha esquecido totalmente a sintaxe da função alternativa - obrigado!
Motim
Os espaços não são necessários <<<para salvar outros quatro caracteres.
Michael Mior
4

Befunge 93-375

Toma uma string binária como entrada.

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

Lê a string. O Bruteforce a grava (a faixa mais vertical à direita) como uma matriz entre o

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

adicionando retículo (idk). Determina a soma das colunas, linhas e dois diagnósticos. Compara esses valores com 3 ("vitória") ou 0 ("perda"), caso contrário, se todos os valores forem iguais a 1 ou 2, então empate ("gato").

AndoDaan
fonte
4

GolfScript, 27 caracteres

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

O formato de entrada é uma sequência composta por oito dígitos octais, cada um (redundantemente) codificando três quadrados consecutivos do quadro:

  • Os três primeiros dígitos codificam uma única linha do quadro, de cima para baixo e da esquerda para a direita.
  • Os três dígitos a seguir codificam uma única coluna do quadro, da esquerda para a direita e de cima para baixo.
  • Os dois dígitos finais codificam cada uma das diagonais (primeiro da parte superior esquerda para a parte inferior direita e depois da parte inferior esquerda para a parte superior direita).

Para codificar uma sequência (linha / coluna / diagonal) de três quadrados como um dígito octal, substitua todos xna sequência por 1 e cada ocom 0, e interprete a sequência resultante de uns e zeros como um número binário entre 0 e 7 inclusive.

Esta formato de entrada é bastante redundante (todas as posições do tabuleiro são codificados, pelo menos, duas vezes, com a posição central codificado quatro vezes), mas não de forma inequívoca representar qualquer estado possível de uma placa de tic-tac-dedo do pé completamente preenchido, e não directamente codificar o vencedor na entrada.

A entrada pode, opcionalmente, conter espaços ou outros delimitadores entre os dígitos. De fato, todo o programa realmente se importa é se a sequência de entrada contém ou não os dígitos 7ou 0.

Por exemplo, o quadro de exemplo:

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

pode ser representado pela entrada:

651 643 50

Por conveniência, aqui está um programa GolfScript para converter um layout de placa de arte ASCII, como mostrado no desafio acima, em uma sequência de entrada adequada para este programa:

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

Este conversor ignora quaisquer caracteres que não sejam xe o, em ambos os casos, em sua entrada. Ele produz uma sequência de um dígito (completa com delimitadores de espaço, como mostrado acima), adequada para alimentar o programa de determinação de vitórias acima, de modo que a concatenação desses dois programas pode ser usada para determinar o vencedor diretamente do quadro de arte ASCII.

Além disso, aqui está um conversor reverso, apenas para demonstrar que a entrada realmente representa inequivocamente a placa:

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

Ps. Aqui está uma demonstração online desta solução.

Ilmari Karonen
fonte
2
O formato de entrada parece um truque, pois grande parte do trabalho acontece na produção da entrada.
Arkku
@Arkku: Bem, sim, é, mas a pergunta diz explicitamente que "você precisa determinar sua estrutura de entrada para o estado - o que você deve explicar." Ele até mostra uma sequência hexadecimal compactada em bits como um exemplo de um formato de entrada válido; a única diferença entre esse e o meu formato de entrada é que eu reorganizo e duplico alguns bits.
Ilmari Karonen
6
É exatamente a duplicação que parece uma trapaça. (por exemplo, que não codificam directamente o vencedor como a presença de sete ou 0 na entrada)
Arkku
Ainda assim, é uma codificação inteligente, é redundante, mas torna a solução muito mais eficiente do que qualquer codificação não redundante!
ARRG
3

Python 2 - 214 bytes

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'

Tenho certeza de que há melhorias a serem feitas.

Para correr:

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

que representa este fórum:

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

Sai com uma NameErrorexceção em todos os casos, exceto cat.

undergroundmonorail
fonte
Whoa, eu nunca soube <<<! +1 apenas por isso.
Greg Hewgill
@GregHewgill É bastante conveniente. ./whatever <<< 'blah blah blah'é o mesmo que echo -n 'blah blah blah' | ./whatevermas sem ter todo um processo separado para echo.
undergroundmonorail
@undergroundmonorail echoem bashé realmente um embutido, então não desembolsar um novo processo
Bob
@GregHewgill é chamado de herestring
3

Haskell, 146 caracteres

Para tornar as coisas interessantes, você determina sua estrutura de entrada para o estado - que você deve explicar.

ESTÁ BEM :). Minha representação de um quadro é um desses 126 caracteres

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

Aqui está a solução em 146 caracteres:

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

E aqui está como ele funciona, como um script 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"
ARRG
fonte
3

JavaScript, 420 caracteres

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'

Nesta versão, scontém um número inteiro que representa o estado do tabuleiro de jogo. É uma matriz de valores em que dois bits representam cada quadrado no quadro:

  • 10 - X
  • 11 - O
  • 00 - Praça vazia

Essa solução usa manipulação de bits para testar cada uma das oito configurações possíveis "três em linha" (as testa duas vezes, uma vez para X e uma vez para O).

Apresento isso com uma minificação menor no meu site Tic-Tac-Toe, onde essa detectWinfunção está em uso como parte de um jogo real de Tic-Tac-Toe.

Stephen Ostermiller
fonte
6
Bem, isso pode ser chamado de bruto, forçando-o.
seequ
2

Ruby, 84 caracteres

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

Solução simples, baseada em RegExp. O formato de entrada é uma sequência binária de 9 dígitos, por exemplo, 110101001para o quadro de exemplo fornecido na pergunta.

Ruby, 78 caracteres

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

Formato de entrada: xxo_xox_oox

Ventero
fonte
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

Formato de entrada: "X" é representado apenas por x, "O" apenas por o. Dentro de cada linha, os caracteres são simultâneos sem espaços, etc. As linhas são separadas por novas linhas.

Gera todas as linhas / colunas / diagonais possíveis, depois filtra [("ooo","lose"),("xxx","win")]pela existência no quadro e depois seleciona a segunda palavra na tupla, para sabermos quais jogadores venceram. Anexamos anteriormente "cat"para que possamos levar o último elemento da lista como nosso vencedor. Se os dois jogadores venceram, "win"será o último (as compreensões da lista mantêm a ordem). Como "cat"sempre é o primeiro, se um vencedor existir, ele será escolhido; caso contrário, um último elemento ainda existe, pois o anexo "cat"garante a não-vacuidade.

EDIT: Raspou 3 caracteres alterando a compreensão da última lista para map.

YawarRaza7349
fonte
1

C, 150 aprox.

Aqui é meia-noite e ainda não testei , mas postarei o conceito de qualquer maneira. Volto amanhã.

O usuário insere dois números octais (eu queria usar o binário, mas, tanto quanto sei, C suporta apenas octal):

a representa o quadrado central, 1 para um X, 0 para um O

b é um número de nove dígitos que representa os quadrados do perímetro, circulando o tabuleiro começando em um canto e terminando no mesmo canto (com repetição apenas desse canto), 1 para um X, 0 para um O.

Existem duas maneiras possíveis de ganhar:

  1. o quadrado central é X ( a= 1) e dois quadrados opostos também são X ( b&b*4096é diferente de zero)

  2. três quadrados de perímetro adjacentes são X ( b/8 & b & b*8é diferente de zero). Essa é apenas uma vitória válida se o quadrado do meio for um quadrado de aresta, não um quadrado de canto; portanto, é necessário aplicar a máscara mtambém, para evitar as caixas quadradas de canto.

Perder é detectado usando a variável c, que é o inverso de 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"));
}
Level River St
fonte
Você esqueceu de aplicar a máscara mna detecção de "perda" - c/8&c&c*8. Voltei a jogar seu código (sem testar seu funcionamento) da seguinte forma: 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 caracteres). O teste repetido foi longo o suficiente para ser extraído em uma função de teste t(); isso remove a necessidade de ce m; as constantes convertidas em hexadecimal para salvar um caractere cada.
Toby Speight
Apenas percebi que printfnão precisa de uma sequência de formato - apenas forneça a sequência de resultados como o formato - ou putsela, pois a pergunta não pede uma nova linha após a saída! (economiza mais 7 caracteres).
Toby Speight
1

Bater, 107 103

Gera e executa um script sed.

Formato de E / S: oxo-oox-xoosaídas lose(use a -para separar linhas). Entrada em stdin. Requer GNU sed para o ccomando.

Eu interpretei a regra 5 como "se a vitória e a derrota forem possíveis, escolha vencer".

Código principal

Esta é a resposta real.

Nada realmente interessante. Ele define $bcomo /cwinsalvar caracteres, define a parte da condição de vitória do script e usa sed y/x/o/\;s$b/close/para converter xpara oe cwinpara close(gerando, assim, as condições de perda). Em seguida, ele envia as duas coisas e ccat(que serão exibidas catse nenhuma condição de vitória / perda for correspondida) para 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"

Código Gerado

Este é o script sed gerado e executado pelo script Bash.

Nas regexes, .corresponde a qualquer caractere e depois deles cTEXTimprime TEXT e sai se a regex for correspondida.

Isso pode ser executado como um script sed independente. Tem 125 caracteres, você pode contar como outra solução.

/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

fonte
1

Python 3, 45

Entrada é entrada i, que é uma lista de números que representam cada linha, coluna e diagonal do tabuleiro de jogo, por exemplo:

X X O
O X O
O O X

é representado por [6, 2, 1, 4, 6, 1, 7, 4].

Código :('cat','lose','win')[2 if 7 in i else 0 in i]

pseudonym117
fonte
1

Dardo - 119

(Veja dartlang.org ).

Versão original usando RegExp: 151 caracteres.

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

A entrada na linha de comando possui 11 caracteres, por exemplo, "xxx | ooo | xxx". Qualquer caractere não xo pode ser usado como delimitador.

Os espaços em branco à esquerda e as novas linhas devem ser omitidos antes da contagem de caracteres, mas cortei o espaço em branco interno sempre que possível. Eu gostaria que houvesse uma maneira menor de fazer a substring.

Versão base de bits recusiva: 119 caracteres. A entrada deve ser um número de 9 bits com 1s representando 'x' e 0s representando '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"));
}
lrn
fonte
1

CJam, 39 38 36 caracteres

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

Este é um código convertido básico para

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

que tem 52 caracteres.

A entrada é simplesmente a representação de string do quadro, começando do canto superior esquerdo, indo linha por linha. Por exemplo:

oxooxooox

o que resulta em uma winsaída. Ou

oxooxoxox

o que resulta em uma catsaída etc.

O código simplesmente faz as seguintes três coisas:

  • q3/_ - Divida a corda em partes de 3, ou seja, por linha
  • _z - Copie a matriz por linha e transponha para a matriz por coluna.
  • __Wf%s4%- Inverta cada linha e vire a diagonal da esquerda para a direita. Esta é a diagonal secundária do quadro.
  • \s4% - Obtenha a diagonal principal do quadro
  • ]` - Enrole tudo na matriz e especifique a matriz.

Agora temos todos os grupos possíveis de 3 do quadro. Simplesmente verificamos a existência de "ooo" e "xxx" para determinar o resultado.

Experimente online aqui

Optimizer
fonte
1

GNU sed, 25 bytes

Se a entrada for uma representação redundante do tabuleiro com visualizações separadas para colunas, linhas e diagonais, como também é usado em outras respostas, o sed é muito adequado para verificar o estado final do jogo com o mínimo de bytes.

Formato de entrada: xxx ooo xxx xox xox xox xox xox (estado da placa retirado da pergunta do OP)

/xxx/cwin
/ooo/close
ccat

Se o formato de entrada não for redundante ( xxx ooo xxx), o código sed acima funcionará apenas se precedido pela linha abaixo, tornando o programa com 96 bytes de comprimento (com o rsinalizador necessário contado).

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

Bash: 208 caracteres

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

Executar bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Inspirado por esta resposta .

Michael Mior
fonte
0

VB.net

Com o exemplo, o fornecimento é codificado como o seguinte padrão de bits

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

Agora podemos determinar o resultado (ou vencedor) fazendo o seguinte.

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"))
Adam Speight
fonte
0

J - 97 bytes

Bem, a abordagem mais simples disponível. A entrada é tomada como 111222333, onde os números representam linhas. Leia da esquerda para a direita. Jogador é xe inimigo é o. Quadrados vazios podem ser qualquer coisa, exceto xou o.

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

Exemplos: (NB. É um comentário)

   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

Código ungolfed uma explicação

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`---- >@{~
seequ
fonte
0

Python 2, 120 bytes

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]

Ou Python, 115 bytes do shell Python (2 ou 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]

A variável board é definida no formato binário descrito na pergunta: 1para X, 0para O, da esquerda para a direita, de cima para baixo. Nesse caso, 101001110representa

XOX
OOX
XXO

O que leva à saída: Cat

Cees Timmerman
fonte
Qual é o formato de entrada?
seequ
0

Python ( 73 62 caracteres)

A entrada são quatro cadeias de letras minúsculas representando quatro visualizações distintas da mesma placa, todas concatenadas em uma única cadeia de caracteres: por linha, por coluna, diagonal direita, diagonal esquerda.

ATUALIZAR

Agradecemos à theRare por apontar isso com um bom contra-exemplo! Cada visualização do painel, juntamente com cada segmento (linha ou coluna) dentro de um painel, deve ser separada por um caractere que não seja um "x" ou um "o" para que a estrutura do painel seja preservada mesmo após a concatenação. As bordas em torno de cada visualização do quadro serão colchetes ("[" e "]"), e o separador entre linhas / colunas será um caractere de barra vertical | | ".

Isso simplifica o algoritmo - basta procurar "xxx" ou "ooo" para ganhar ou perder, respectivamente. Caso contrário, é um empate (gato).

Por exemplo, o quadro (leitura da esquerda para a direita, de cima para baixo) ...

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

... é representado como "[xxx | xox | oxo]" (por linhas) + "[xxo | xox | xxo]" (por colunas) + "[xoo]" (diag da direita) + [xoo] "(esquerda diag) = "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]".

Esta instrução Python imprime o resultado do jogo, dada a variável s como entrada:

print 'win' if 'xxx' in s else 'lose' if 'ooo' in s else 'cat'
prumo
fonte
Isso funciona para o conselho OXX XOO XOX(deve ser gato)?
seequ
Não ... não, não faz. Boa pegada! Acho que minha solução foi um pouco simples demais ... Opa!
bob
Não posso dizer que esse tipo de solução não passou pela minha cabeça. :)
veja
0

Haskell (69 caracteres)

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

É preciso a mesma entrada descrita nesta resposta . Mais especificamente, a entrada são 8 valores octais, descrevendo o valor binário de cada linha, coluna e diagonal. O código faz com que todas as instâncias de 7 "vença", todas as instâncias de 0 "percam" e remove todo o resto. Em seguida, ele adiciona "gato" ao final e pega os 4 primeiros caracteres do resultado.

Haverá 4 respostas possíveis: "perder", "gato", "vencer" seguido de um 'l' e "vencer" seguido de um 'c', que as regras não proíbem :)

Exemplo de uso:

i "65153806" --outputs "lose"
TheBrownMotie
fonte
0

J: 83

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

Uso: basta acrescentar uma sequência de x e o e observar o trabalho mágico. por exemplo. 'xxxoooxxx'.

O verbo interno (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))basicamente encaixa a matriz binária original, com a transposição encaixotada e as 2 diagonais. Esses resultados são arrasados; somas de linha são tomadas para determinar vitórias e, em seguida, somadas. mais chamarei esse verbo Inner.

Para encontrar o vencedor, a diferença das pontuações entre as matrizes binárias normal e inversa é tomada pelo gancho (-&Inner -.).

O restante do código simplesmente produz as saídas e seleciona a correta.

jpjacobs
fonte
0

JavaScript, 133 , 114 caracteres

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

A entrada ié uma string simples com delimitadores para as linhas, ou seja,100|001|100

Editar: atualizei meu método para substituir os 1s na regex por zeros para verificar o caso de perda.

thomaux
fonte
Você pode remover os espaços ao redor =e as aspas ao redor da regex literal. Além disso, 1...é um caractere menor que 1.{3}.
usar o seguinte código
11
r.test(i)também é um caractere menor que i.match(r).
usar o seguinte código
0

J - 56 (26?) Char

A entrada recebe uma matriz 3x3 de nove caracteres, porque J pode suportar isso como um tipo de dados, LOL.

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

Exemplos:

   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

Se for permitida a codificação Golfscriptish de dígitos octais representando redundantemente o estado de cada linha, coluna e diagonal, são apenas 26 caracteres:

   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
algoritmshark
fonte
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)

A entrada é um número hexadecimal. É praticamente uma tradução da solução ruby ​​para o T-SQL bastante agradável e arrumada.

Michael B
fonte
0

Javascript 1.6, 71 caracteres

Estou assumindo entrada como uma matriz gameque contém cada linha, cada coluna e cada diag como uma seqüência de 3 caracteres. Semelhante à resposta de bob , mas vem em uma matriz, não como uma sequência concatenada.

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

EDIT @ nyuszika7h 's comentário (67 caracteres)

alert(~game.indexOf("xxx")?"win":~game.indexOf("ooo")?"lose":"cat")
JNF
fonte
Você pode usar em ~game.indexOf("xxx")vez de game.indexOf("xxx")>=0, o mesmo para o outro.
precisa saber é o seguinte
0

Java 7, 260 bytes

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

Casos não testados e de teste:

Experimente aqui.

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

Resultado:

loose
win
cat
Kevin Cruijssen
fonte
0

APL (NARS), 69 caracteres, 138 bytes

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

A entrada deve ser uma matriz 3x3 ou uma matriz linear de 9 elementos que pode ser apenas 1 (para X) e 0 (para O), o resultado será "gato" se ninguém vencer, "perder" se O vencer ", vencer "se X vencer. Não há verificação de uma placa ou entrada inválida, uma matriz possui menos de 9 elementos ou mais ou verifica cada elemento <2.

Como um comentário: ele converteria a entrada em uma matriz 3x3 e criaria uma matriz denominada "x", em que os elementos são a soma de cada coluna de linha e diagonal.

Alguns testes, veja o exemplo mostrado de outros:

  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
RosLuP
fonte