fundo
Nos jogos Bejeweled e similares, o jogador deve trocar quaisquer duas gemas adjacentes (sem diagonais) em uma grade de gemas 8x8 para combinar três da mesma cor seguidas. As gemas podem ser combinadas horizontalmente ou verticalmente. A jogabilidade continua até que não exista nenhum movimento que possa ser feito, resultando em três seguidas, altura em que o jogo termina.
Tarefa
O objetivo é escrever um programa que determine se um jogo de Bejeweled ainda não terminou. Em outras palavras, ele deve verificar se há uma possível movimentação que faça pelo menos três seguidas. Pode haver mais de três gemas seguidas e ainda é uma jogada válida.
Entrada
Seu programa deve aceitar via entrada padrão uma representação 8x8 de uma grade Bejeweled. Cada uma das sete cores de gemas será representada por um dígito de 1 a 7. Cada linha conterá uma linha e serão inseridas 8 linhas, cada uma consistindo em 8 dígitos. Veja os exemplos. Você pode assumir que a entrada sempre seguirá esse formato e nunca conterá três em uma linha.
Saída
O programa deve então enviar (para saída padrão) yes
ou no
dependendo da existência de pelo menos um movimento válido que resultaria em três ou mais gemas seguidas. Seu programa não deve produzir nada além de uma única instância de um yes
ou outro no
.
Regras
Seu programa não deve usar arquivos ou recursos externos, argumentos de linha de comando ou exigir um determinado nome de arquivo. O programa com o menor número de bytes em seu código-fonte vence.
Exemplos
Entrada:
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
Saída: yes
Entrada:
35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465
Saída: no
Veja a resposta do MT0 abaixo para casos de teste adicionais.
Respostas:
Solução original: JavaScript -
261255228227179153 caracteresSupondo que a sequência a ser testada esteja na variável
s
(para torná-la uma funçãof
, incluaf=s=>
no início do código ou, caso contrário, obtenha a entrada de um prompt e substituas
porprompt()
).As saídas são para o console.
3 rd Solução: JavaScript (ECMAScript 6) - 178 Characters
Tomei a 2 nd solução, abaixo, (que usa expressões regulares para verificar se há caracteres em determinadas configurações) e reformulado para apenas verificar a string de caracteres idênticos nas mesmas configurações sem o uso de expressões regulares.
A cadeia de base-36
"2313ab1b8a2a78188h9haj9j8iaiir9r"
dá pares de deslocamentos para verificar - ou seja, os pares de23
resultados na verificação de se i th carácter é idêntico ao do (i + 2) th personagem e a (i + 3) th personagem (o equivalente da expressão regular(.).\1\1
- com algumas verificações adicionais para garantir que o caractere não idêntico não seja uma nova linha).2 nd solução: JavaScript (ECMAScript 6) - 204 caracteres
Constrói várias expressões regulares (veja abaixo para obter mais detalhes) usando pares de valores retirados da string Base-18
10907160789879h8
e realizaOR
todos os testes. Para reduzi-lo ainda mais, observe que as expressões regulares vêm em pares, onde um é o "reverso" do outro (ignorando as Expressões regulares de 3 em linha horizontal e verticalmente, pois o OP afirma que nunca estarão presentes - se você deseja adicionar esses testes novamente no anexo0088
à string Base-18).Explicação
Comece com 16 expressões regulares, cobrindo todas as configurações possíveis de movimentos válidos:
( Nota: os regexs para-3-em-linha horizontal (0 ° ) e verticalmente (parte do 9 th ) são irrelevantes como os estados que OP entradas correspondentes estes nunca estarão presentes. )
Testar cada um deles em relação à entrada determinará se uma movimentação válida dessa configuração pode ser encontrada.
No entanto, as expressões regulares podem ser combinadas para fornecer 6:
Eles podem ser combinados em uma única expressão regular:
O que só precisa ser testado com relação à entrada.
Casos de teste
Alguns casos de teste que outras pessoas podem achar úteis (não estão de acordo com o formato de entrada de uso apenas dos dígitos 1 a 7, mas são facilmente corrigidos e são apenas uma grade 8x4 - pois esse é o mínimo necessário para um teste de todas as entradas válidas )
No formato de um mapa da sequência de entrada com a qual das 16 expressões regulares acima corresponde.
Editar 1
Substituir
\d
s por.
- salva 6 caracteres.Editar 2
Substitua
(?:.|\n)
por[\s\S]
grupos extra-captura e removidos e referências anteriores atualizadas (conforme sugerido pelo m-buettner ) e adicionadas na saída yes / no.Editar 3
Editar 4
Adicionada outra solução (mais curta) e mais dois casos de testes não correspondentes.
Editar 5
Editar 6
fonte
?'yes':'no'
contagem de caracteres em sua justiça, porque ela está nos requisitos e todos os outros a estão usando..
corresponder a qualquer caractere, incluindo nova linha? Com o Perl, o regexp combinado é uma mera string de 129 bytes (que, sendo preguiçoso, compilei com o Regexp :: Assemble ), portanto, todo o programa Perl tem cerca de 150 bytes..{8}|.{9}
com.{8,9}
e.{7}|.{8}
com.{7,8}
Python 383
Apenas uma única linha * de Python!
* Bem, com ponto-e-vírgula, mas isso ainda não é trivial em python (os linux one-liners são divertidos! )
fonte
Node.js - Solução ingênua - 905 bytes
Bem, ainda não tenho respostas, então postarei uma solução realmente ingênua no Node.js
Ele realiza todos os movimentos possíveis e, em seguida, testa o painel resultante para ver se há três seguidos.
Golfed (com o compilador de fechamento do google) (algumas coisas hacky lá dentro, como! 0 e! 1; nem tenho certeza do que ele fez com minha troca XOR)
Observe que escrevi tudo isso no meu celular e não tenho tempo para testá-lo ou algo assim. Comente se houver algum erro, eu mesmo verificarei mais tarde.
A versão legível humana pré-golfe
fonte
Perl,
11496959392878685 bytesInclui + para
-a0p
Execute com a entrada em STDIN:
bejeweled.pl
:Isso combina uma solução regex horizontal de direção única com rotações
Explicação:
Nesta solução, girarei repetidamente e faça os 4 testes a seguir:
Onde
\C
está "qualquer caractere" (ao contrário.
disso, inclui nova linha). Exceto que isso\C
foi preterido e leva a avisos, então eu uso\H
(espaço não horizontal) em vez disso, o que é bom o suficiente para capturar todos os dígitos e nova linha.Após 4 rotações, todos os 16 testes serão necessários.
fonte
Python3, 314B
Altere 8, 5 na linha 6 e 8s na linha 9 para manipular tamanhos de entrada arbitrariamente grandes; também não se importa com o valor de cada valor, para que você possa alimentá-lo:
e ele retornará
yes
.Anotações
fonte
GNU sed 255 + 2 = 257B
Eu pensei que isso não seria tão bom quanto o python, mas agora é: - / Estive sem acesso à Internet hoje, então me ocupei em resolver isso no sed :). Precisa ser chamado com a bandeira -r, ou seja,
sed -rf command.sed < input
adicionei 2 à minha pontuação.Como funciona:
fonte
Ruby, 201 bytes
Fiquei desapontado por não encontrar soluções para esse grande desafio que não usem força regex ou força bruta (embora sejam ótimas), então escrevi uma. É necessário entrada no STDIN.
O principal algoritmo aritmético bit a bit é derivado desta resposta fantástica no Game Development Stack Exchange da @leander.
Ruby lambda, 181 bytes
Aqui está como um lambda que pega uma string e retorna
true
oufalse
:Veja em repl.it: https://repl.it/ColJ/2
Ungolfed & explicação
O código itera sobre os dígitos "1" a "9." Cada iteração possui duas etapas distintas:
O primeiro passo é a transformação da placa, que você pode ver no
s.scan(n)
bloco no código não-destruído. Ele transforma a placa em uma matriz de 8 números inteiros, um para cada linha, tratando os dígitos correspondentes como 1s e todos os outros como 0s em uma sequência binária. Por exemplo, pegue a linha12231123
. Na primeira iteração, isso se tornará a sequência binária10001100
(todos os 1s se tornam - er, permanecem - 1s e todos os outros dígitos se tornam 0s), que é o número decimal 140. Na segunda iteração, a mesma linha se torna01100010
(todos os 2s se tornam 2s e todos os outros dígitos se tornam 0s) ou decimal 98.Ele executa simultaneamente uma segunda transformação, que é a mesma que a primeira, mas com a placa girada 90 graus. Isso nos permite usar a mesma lógica para fazer correspondências horizontais das verticais. Por uma questão de simplicidade, concatena as duas placas em uma única longa e com zero no começo, meio (para separar as duas placas) e final para preenchimento.
O segundo passo é procurar possíveis correspondências, que você pode ver no
each_cons(3).any?
bloco. As linhas transformadas (que agora são números inteiros de 8 bits) são registradas em grupos (sobrepostos) de três linhas ( x , y , z ) usando aritmética bit a bit. Cada grupo é verificado para ver se uma correspondência pode ser feita na linha y , deslocando uma peça na linha y ou deslocando uma peça para y de x ou z . Como não existe uma "linha" zero antes e depois das linhas originais e rotativas das placas, não precisamos verificar se estamos na primeira ou na última linha de uma placa.Se nenhuma correspondência for encontrada, ela continuará para a próxima iteração.
fonte