Desafio
Dada uma placa de jogo da velha em qualquer formato, determine se é válida ou não. Se um tabuleiro puder ser o resultado de um jogo da velha, então é válido. Por exemplo, este quadro é válido:
XOX OXO XOXPelo contrário, este fórum é inválido:
XXX XXO OOO
Entrada
- Um tabuleiro completo (9/9) de jogo da velha (o resultado, não o jogo).
Regras
- O formato de entrada deve ser capaz de representar todas as 512 placas de entrada possíveis. Ele deve ser especificado, juntamente com as instruções para criá-lo, se estiver obscuro / claro. Você deve indicar as marcas do quadro individualmente.
- Deve haver duas saídas possíveis, uma para validade e outra para invalidez.
- Você pode assumir que o tabuleiro não possui pontos vazios.
Casos de teste
Válido:
XOX OXO XOX XOX XOX OXO XOO OOX OXX OXO XOX OXO
Inválido:
XXX XXX XXX OOO OOO OOO XXX OOO XXX OOO OOX XXX XXO OXO OOX
Uma ajudinha?
Uma diretoria é considerada válida (para esse desafio) se e somente se as duas condições a seguir forem válidas:
- Existem 5 X e 4 O ou 4 X e 5 O. Por exemplo,
XXX OXO XXX
é considerado inválido, porque existem 7 Xs e 2 Os. - Apenas o jogador com 5 pontos venceu ou nenhum deles venceu. Por exemplo,
XXX OOO OOX
é considerado inválido, pois a linha deO
s ou a linha deX
s serão formadas primeiro. Os dois jogadores não podem ter sua vez simultaneamente.
O atual vencedor é ...
... resposta da geléia de ais523 , com surpreendentes 26 bytes!
code-golf
decision-problem
tic-tac-toe
Erik, o Outgolfer
fonte
fonte
O O O
X O X
X O X
, para mostrar que o mesmo jogador pode ter uma linha horizontal e vertical.Respostas:
Geléia , 26 bytes
Experimente online!
O formato de entrada é um pouco incomum; é uma string que representa o quadro, mas com as novas linhas do Windows (retorno de carro seguido de nova linha). Por exemplo
XXO\r\nOXO\r\nOOX
,. (Na verdade, qualquer string de preenchimento de dois caracteres entre as linhas funciona, mas as novas linhas do Windows são muito mais defensáveis do que as outras opções.)A ideia básica é que procuremos caracteres que apareçam 4 vezes na entrada, mas não tenham três ocorrências igualmente espaçadas na string original. Com dois ou mais caracteres de preenchimento entre as linhas de uma grade 3 × 3, todas as linhas horizontais, verticais e diagonais são espaçadas igualmente, mas nenhuma outra linha espaçada uniformemente pode ter três elementos.
Explicação:
A
ð
eµ
s são separadores de cadeia , os quais dividem o programa em múltiplas partes que são cada um independente. Substituí-os por espaços abaixo, para tornar as coisas um pouco mais claras.Em outras palavras, encontramos a lista de caracteres que aparecem exatamente quatro vezes na entrada e fazemos uma lista que consiste em três cópias de cada um deles; encontramos a lista de todas as subsequências espaçadas igualmente na string original; e se subtrairmos o segundo do primeiro, queremos que o resultado tenha o comprimento 1 (ou seja, um jogador jogou quatro vezes, mas não venceu). Note que, como estamos em uma grade 3 × 3 e cada quadrado está cheio, é impossível que os dois jogadores joguem quatro vezes. No Jelly, 1 é verdade, 0 é falsey, portanto, não precisamos fazer nada de especial para converter a lista resultante em um booleano. (
µL
Porém, é necessário, porque, caso contrário, ambos“XXX”
e“OOO”
seriam possíveis valores reais de saída, e a pergunta exige que todas as placas válidas produzam a mesma saída.)fonte
JavaScript (ES6),
8887 bytesToma entrada como uma cadeia de 9
0
e1
caracteres e retorna1
para válido,0
para inválido. Classificamos os caracteres em ordem. Se os três caracteres do meio agora são os mesmos, o tabuleiro é inválido, pois há muitos de uma peça. Caso contrário, convertemos a placa original em binária, invertendo os bits se houver mais0
s que1
s. Nesse ponto, o quadro é válido se0
não tiver uma linha de três; portanto, simplesmente testamos todas as oito linhas por meio de uma matriz de máscaras de bits. Editar: salvou 1 byte graças a @ETHproductions.fonte
Python 3,
13112712510096 bytesPara uma abordagem algorítmica diferente (e que será realmente adequada para essas linguagens de golfe de vários bytes com compactação embutida), em vez de calcular se a placa é válida, vamos ter um número de 512 bits em que cada bit representa se deve ou não uma placa específica é válida ou não e passa um valor binário que representa a placa. Além disso, devido à simetria, a segunda metade da tabela pode ser eliminada, juntamente com um monte de zeros:
O valor do teste:
É representado como o valor binário
0b111010111
e a função retorna um valor diferente de zero se a placa for válida.fonte
a&(1<<b)
não precisam de colchetes.if b>255:b=511-b
!if
.Lote, 140 bytes
Recebe entrada como nove argumentos e saídas de linha de comando separados
1
para válidos e0
inválidos. Funciona rastreando o número de vezes que vê umaO
linha ortogonal deOOO
ouXXX
. Convenientemente, o Lote nos permite executar aritmética inteira indiretamente, portanto, não estamos incrementando,%%l
mas algumas variáveis (embora apenas nos interessemos pelas três variáveis mencionadas). Precisamos, então, testar se ouX
não ganhou e há cincoO
segundos ou queO
não venceu e há quatroO
segundos.fonte
Mathematica,
8275 bytesAgradecemos a Martin Ender por economizar 7 bytes!
Função sem nome, tendo uma lista aninhada 3x3 de 1s e 0s como entrada e saída
True
ouFalse
.Utiliza alguma flexibilidade prática da
Total
função (aquit
indicada para ): dado um exemplo de matrize = { {1,2,3} , {4,5,6} , {7,8,9} }
, o comandot[e]
soma os três vetores (aqui produzindo{12,15,18}
); o comandot/@e
soma cada sub-lista individualmente (aqui produzindo{6,15,24}
); e o comandoe~t~2
soma todos os nove elementos (aqui rendendo45
).Então, primeiro testamos, com
3<(b=#~t~2)<6
, se o número total de 1s é 4 ou 5; se não, saímos comFalse
. Nesse caso, usamosc=If[b>4,1-#,#]
para forçar a existência de quatro 1s, não cinco. Em seguida, calculamos as somas da colunat[c]
, as somas da linhat/@c
, a soma da diagonal principalTr@c
e a soma da diagonal opostaTr@Reverse~c
e usamos~FreeQ~3
para verificar se as3
falhas não aparecem em nenhum nível nessas somas calculadas.Nota lateral divertida: ao contrário da maioria das aparências neste site, aqui
Tr
não é usado para somar uma lista unidimensional, mas na verdade é usado como projetado - para calcular o traço de uma matriz bidimensional!fonte
Pitão - 36 bytes
Incluo diagas e uso dois ternários.
Suíte de teste
fonte
JavaScript (ES6), 101 bytes
Recebe a entrada como uma máscara binária de 9 bits em que
X = 1
eO = 0
(MSB = célula superior esquerda, LSB = célula inferior direita).Casos de teste
Mostrar snippet de código
fonte
Python 2,
1581321099291123 bytesInput é uma lista / tupla de linhas, cada uma com três tuplas de strings, por exemplo:
[('X', 'O', 'X'), ('O', 'X', 'O'), ('X', 'O', 'X')]
Economizou alguns bytes ignorando diagonais pela resposta de @ Maltysen, que também reduziu a expressão a seguir.Obrigado @vaultah por salvar1718 bytes.A verificação das diagonais acaba sendo necessária, o que removeu muitas das economias acima.
Experimente aqui.
Explicação
f
é a entrada achatada para fatiar.w
contém os personagens com seqüências vencedoras.Conte as ocorrências de cada personagem vencedor, que será 0 se
w
estiver vazio ou 5 selen(w)
for 1. A soma 10 quando ambos tiverem uma sequência vencedora é impossível. O vencedor com 5 implica que o perdedor tem 4. Você não pode ter> 5 sem uma sequência vencedora.fonte
lambda b:len({x[0]for x in b+zip(*b)if len(set(x))==1})<2and set(map(
b.count,'XO'))=={4,5}
salva alguns bytes....and{4,5}==set(map(
b.count,'XO'))
salva mais um byte.R,
8882 bytesTodas as combinações de três números inteiros de 1 a 9 que somam 15 são as linhas / colunas / diagonais do quadrado mostrado abaixo.
A função recebe a entrada como um vetor de booleanos, T para "X", F para "O", que é a representação achatada da placa. MAS, estes são reordenados para que seu índice seja o mesmo que o número no quadrado, na ordem (2,7,6,9,5,1,4,3,8). Essa ordem pode ser alcançada aplainando a placa da maneira normal e depois cortando em c (6,1,8,7,5,3,2,9,4). Então, é isso
é representado como:
qual é:
A função primeiro determina se existe um jogador com exatamente quatro marcas. Nesse caso, a função usa o fato das coisas que somam até 15 para determinar se esse jogador tem três em linha (o tabuleiro é inválido se esse jogador tiver).
Se você quisesse usar uma placa achatada convencionalmente como entrada, o código teria a seguinte aparência:
Eu sou novo nisso, conselhos seriam apreciados.
fonte
if()
:f=function(x)
if(sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)
. Não é extensivamente testado. Os backticks arruinam o código, mas ébacktick if backtick(
.x=scan();
if(sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)
e entrada como1
e0
. 82 bytes.JavaScript (ES6),
145139131127 bytesEntrada como uma cadeia de caracteres separada por espaço, como
"XOX OXO XOX"
. Saídas1
para uma placa inválida,0
para uma válida. Obviamente, essa não é a melhor técnica, pelo menos não com JavaScript ...Isso basicamente verifica se os seguintes itens se mantêm:
O
s, EO regex é verificar se um jogo foi decidido. Ele corresponde a uma placa se houver execuções de três caracteres com 0 (linha), 2 (diagonal para baixo à direita), 3 (coluna) ou 4 caracteres (diagonal para a esquerda) que separam cada par.
Snippet de teste
Mostrar snippet de código
fonte
Ruby,
104 9991 bytesFormato de entrada: sequência binária de 9 símbolos (0s e 1s) representando a placa, por exemplo, o primeiro caso de teste
101010101
. Primeiro converta-o para um número binário, verifique se o número de pop-ups é 4 ou 5, se é 5, inverta o número para que sempre tenhamos 4. Verifique se três deles estão alinhados (mascaramento com horizontal, vertical, diagonal).TL; DR : Retorna false se um jogador com 4 pontos conquistou, caso contrário, true.
Obrigado Jordan pelos comentários,
Não consigo reproduzir a sequência UTF-8 que salvaria outro byte.
fonte
.select{...}[0]
por.find{...}
."8ǀĤITđ".unpack("U*")
(caso algo se perca na conversão, a sequência é o resultado da chamadapack("U*")
na matriz original; são 12 bytes).any?
vez denone?
inverter a saída e salvar um byte inteiro?Perl 6 ,
10399 bytesUm lambda que aceita uma lista de listas como
(('X','O','X'), ('O','X','O'), ('X','O','X'))
e retorna um Bool.Funciona assim:
c
. (Se nenhuma marca aparecer exatamente 5 vezes, isso conterá um valor falso)c
é verdade e cada linha vencedora é do tipoc
.fonte
PHP, 125 bytes
Tive a mesma ideia que Arnauld : a placa é válida se houver 4 ou 5 bits configurados e
X
ouO
ou ninguém tiver uma raia (mas não as duas).Para gerar entrada do campo, substitua
X
por1
eO
com0
, junte linhas e converte binário em decimal, forneça como argumento da linha de comando.impressões
1
válidas; saída vazia por inválido. Corra com-r
.demolir
fonte
Rápido, 178 bytes
fonte
ES6 (Javacript)
130,138, 117 bytesEDITAR% S:
Uma abordagem extremamente direta. Provavelmente pode ser jogado um pouco mais longe.
Aceita entrada como 9 argumentos separados, 1es e 0es
Argumentos: 1-3 - primeira linha, 4-6 - segunda linha, 7-9 - terceira linha.
Golfe
"Cama de teste" interativa
fonte
[1,0,1,1,0,1,0,1,0]
(XOX XOX OXO
).a+b+c+d+e+f+g+H+i
vez deF.reduce((r,c)=>r+=c*1)
(nesse momento não precisaF
) b) escrever.includes(C)
(e continuar comC
o valor do inline )?OOO XXX OXO
um fracasso?