Martin Ender atingiu recentemente 100K e criou algumas linguagens bastante impressionantes . Vamos nos divertir um pouco com um deles, Hexagony (e um pouco de regex para Retina )
Como uma breve visão geral, você precisa escrever um programa que insira uma grade Hexagony e determine se existe um caminho nessa grade que corresponda a uma sequência de texto
Gerando
Hexagony gera hexágonos a partir de uma sequência de texto usando as seguintes etapas:
- Calcular o tamanho mínimo do hexágono (pegue o comprimento da corda e arredonde para o número hexadecimal mais próximo )
- Quebrando o texto em um hexágono do tamanho acima
- Preenchendo os locais restantes com
.
.
Por exemplo, a sequência de texto abcdefghijklm
requer um hexágono de comprimento lateral 3 e, portanto, se torna:
a b c
d e f g
h i j k l
m . . .
. . .
Agora, observe que existem 6 direções possíveis que você pode percorrer em um hexágono. Por exemplo, no hexágono acima, e
é adjacente a abfjid
.
Invólucro
Além disso, no Hexagony, os hexágonos envolvem:
. . . . . a . . . . f . . a . .
a b c d e . . b . . . . g . . . b . . f
. . . . . . g . . c . . . . h . . a . c . . g .
. . . . . . . . h . . d . . . . u . . b . . d . . h . .
f g h i j k . i . . e . . j . . c . e . . i . .
. . . . . . j . . f k . . d . . . j . .
. . . . . k . . . . e . . k . .
Se você observar o segundo e o quarto exemplo, observe como a
e k
estão nos mesmos pontos, apesar de estar seguindo em direções diferentes. Devido a esse fato, esses pontos são adjacentes apenas a 5 outros locais .
Para deixar isso mais claro:
a b c d
e f g h i
j k l m n o
p q r s t u v
w x y z A B
C D E F G
H I J K
- As arestas envolvem o vizinho oposto (
b->I
eG->j
). - Os cantos superior / inferior são agrupados no canto central oposto e para cima / para baixo (
d->K,p
eH->a,v
). - Os cantos centrais são agrupados nos cantos superior e inferior (
v->a,H
)
Caminhos
Um caminho para ser uma sequência de locais adjacentes sem retornar ao mesmo local.
a b c
d e f g
h i f k l
m . . .
. . .
No hexágono acima, aefkgm
é um caminho válido. No entanto, abfd
não é um caminho válido ( f
e d
não é adjacente) e abea
não é válido (retorna ao a
local).
Podemos usar esses caminhos para corresponder ao texto (como regex) . Um caractere alfanumérico corresponde a si mesmo (e somente a ele) e a .
corresponde a qualquer caractere. Por exemplo, o caminho aej..lgm
iria corresponder aej..lgm
, aejAAlgm
, aeja.lgm
, ou aej^%gm
.
Entrada / Saída
Seu programa deve ter duas strings (em qualquer ordem). A primeira sequência não será vazia e consistirá apenas em caracteres alfanuméricos [a-zA-Z0-9]
. Isso representará o hexágono em que você está operando. A segunda sequência será composta por caracteres imprimíveis.
Você precisa retornar um valor verdadeiro se houver um caminho no hexágono que corresponda à sequência de texto fornecida, caso contrário, um valor falso.
Casos de teste
Verdade:
"a","a"
"ab","a"
"ab","b"
"ab","ba"
"ab","aba"
"ab","&"
"ab","#7.J!"
"ab","aaaaaa"
"ab","bgjneta"
"ab","cebtmaa"
"abcdefg","dfabcg"
"AbCDeFG","GCbAeFD"
"aaaabbb","aaababb"
"abcdefghijklmnopqrs","alq"
"abcdefghijklmnopqrs","aqnmiedh"
"abcdefghijklmnopqrs","adhcgkorbefjimnqlps"
"11122233344455","12341345123245"
"abcdefgh","h%a"
"abcdefghijklm","a)(@#.*b"
"abcdefghijklm","a)(@#.*i"
"abcdefghij","ja"
"abcdefghijklmno","kgfeia"
"abcdefghijklmno","mmmmmiea"
"abcdefghijklmno","mmmmmlae"
"abcdefghijklmno","ja"
"abcdefghijklmnopqrs","eijfbadhmnokgcsrql"
Falsy:
"a","b"
"a","%"
"a","."
"a","aa"
"a","a."
"ab","#7.J!*"
"ab","aaaaaaa"
"ab","aaaabaaa"
"ab","123456"
"abcdefg","bfgedac"
"abcdefg","gecafdb"
"abcdefg","GCbaeFD"
"aaaabbb","aaaaabb"
"abcdefghijklmnopqrs","aqrcgf"
"abcdefghijklmnopqrs","adhlcgknbeifjm"
"abcdefghijklmnopqrs","ja"
"abcdefghijklm","a)(@#.*&"
"abcdefghijklmno","a)(@bfeijk"
"abcdefghijklmno","kgfeic"
"abcdefghijklmno","mmmmmmiea"
Como é um código de golfe , faça suas respostas o mais curtas possível no seu idioma favorito.
fonte
Respostas:
Retina , 744 bytes
Desculpe pessoal, não há Hexagony desta vez ...
A contagem de bytes assume a codificação ISO 8859-1.
Espera a sequência de destino na primeira linha e o hexágono na segunda linha da entrada. Imprime
0
ou de1
acordo.Experimente online! (A primeira linha ativa um conjunto de testes, onde cada linha é um caso de teste, usando
¦
para separação em vez de um avanço de linha.)A maneira correta de resolver esse desafio é com uma regex, é claro. ;) E se não fosse o fato de que esse desafio também envolve o procedimento de desdobramento do hexágono , essa resposta realmente consistiria em nada além de um único regex de ~ 600 bytes de comprimento.
Isso ainda não está bem otimizado, mas estou muito feliz com o resultado (minha primeira versão de trabalho, depois de remover grupos nomeados e outras coisas necessárias para a sanidade, ficou em torno de 1000 bytes). Eu acho que poderia economizar cerca de 10 bytes trocando a ordem da string e do hexágono, mas isso exigiria uma reescrita completa da regex no final, o que não estou me sentindo bem agora. Também há uma economia de 2 bytes ao se omitir o
G
palco, mas isso diminui consideravelmente a solução, então esperarei fazendo essa alteração até ter certeza de que joguei isso da melhor maneira possível.Explicação
A parte principal desta solução faz uso extensivo de grupos de balanceamento , por isso recomendo a leitura deles, se você quiser entender como isso funciona em detalhes (não vou culpá-lo se não o fizer ...).
A primeira parte da solução (ou seja, tudo, exceto as duas últimas linhas) é uma versão modificada da minha resposta para Desdobrar o código fonte do Hexagony . Ele constrói o hexágono, deixando a string de destino intocada (e na verdade constrói o hexágono antes da string de destino). Fiz algumas alterações no código anterior para salvar bytes:
×
vez de um espaço, para que não entre em conflito com os espaços em potencial na entrada._
vez disso.
, para que as células da grade possam ser identificadas de maneira confiável como caracteres de palavra.Aqui está um exemplo. Para o seguinte caso de teste:
Nós temos:
Compare isso com o layout usual do hexágono:
Podemos ver que os vizinhos são agora todos os 8 vizinhos de Moore habituais, exceto os vizinhos noroeste e sudeste. Portanto, precisamos verificar a adjacência horizontal, vertical e sudoeste / nordeste (bem e depois existem as bordas da embalagem). Usar esse layout mais compacto também tem o bônus de poder usá-los
××
no final para determinar o tamanho do hexágono rapidamente quando precisarmos.Depois que esse formulário foi construído, fazemos mais uma alteração na cadeia inteira:
Isso substitui os dígitos pelas letras ASCII estendidas
Como eles são substituídos no hexágono e na sequência de destino, isso não afetará se a sequência é correspondida ou não. Além disso, como são letras
\w
e\b
ainda as identificam como células hexagonais. O benefício de fazer essa substituição é que agora podemos usar\D
no próximo regex para corresponder a qualquer caractere (especificamente, feeds de linha e caracteres não feed de linha). Não podemos usar as
opção para fazer isso, porque precisaremos.
corresponder caracteres que não sejam de avanço de linha em vários lugares.Agora, o último bit: determinar se algum caminho corresponde à nossa string especificada. Isso é feito com um único regex monstruoso. Você pode se perguntar por quê?!?! Bem, isso é fundamentalmente um problema de retorno: você começa em algum lugar e tenta um caminho, desde que corresponda à string, e uma vez que não retorna, tenta um vizinho diferente do último caractere que funcionou. A única coisaque você recebe de graça quando trabalha com regex está retornando. Essa é literalmente a única coisa que o mecanismo regex faz. Portanto, se apenas encontrarmos uma maneira de descrever um caminho válido (o que é bastante complicado para esse tipo de problema, mas definitivamente possível com grupos de balanceamento), o mecanismo de expressão regular resolverá encontrar esse caminho entre todos os possíveis para nós. Certamente seria possível implementar a pesquisa manualmente com vários estágios ( e já fiz isso no passado ), mas duvido que seja mais curto nesse caso específico.
Um problema ao implementar isso com uma regex é que não podemos tecer arbitrariamente o cursor do mecanismo de regex para frente e para trás através da string durante o retrocesso (o que precisaríamos, pois o caminho pode subir ou descer). Então, em vez disso, mantemos o controle de nosso próprio "cursor" em um grupo de captura e o atualizamos a cada passo (podemos mover temporariamente para a posição do cursor com uma olhada). Isso também nos permite armazenar todas as posições anteriores que usaremos para verificar se não visitamos a posição atual antes.
Então vamos fazer isso. Aqui está uma versão um pouco mais saudável da regex, com grupos nomeados, indentação, ordem menos aleatória de vizinhos e alguns comentários:
Espero que a idéia geral seja mais ou menos clara disso. Como um exemplo de como um desses movimentos ao longo do caminho funciona, vejamos o bit que move o cursor para o sul:
Lembre-se de que os lookbehinds devem ser lidos da direita para a esquerda (ou de baixo para cima), porque essa é a ordem em que são executados:
Observe que não é necessário colocar uma âncora na frente do
\k<pos>
para garantir que isso realmente chegue ao início da string.<pos>
sempre começa com uma quantidade×
que não pode ser encontrada em nenhum outro lugar; portanto, isso já atua como uma âncora implícita.Não quero inchar este post mais do que o necessário, por isso não entrarei nos outros 11 casos em detalhes, mas, em princípio, todos funcionam da mesma forma. Verificamos que isso
<next>
pode ser encontrado em alguma direção específica (admissível) a partir da antiga posição do cursor com a ajuda de grupos de balanceamento e, em seguida, armazenamos a string até essa correspondência como a nova posição do cursor<pos>
.fonte
Python 3,
990943770709 bytesPrimeira resposta, yay!
EDIT: Criação de lista de adjacências com golfe. Agora eu uso uma fórmula um pouco diferente
EDIT 2: Removido cotão desnecessário, jogou muito mais.
EDIT 3: Encurtou o código para conversão do índice na lista para coordenadas, jogou mais algumas coisas.
A maioria dos bytes está relacionada à criação da lista de adjacências (ela tem mais potencial para ser jogada no golfe). A partir de então, é uma simples questão de forçar brutalmente a solução (o que eu posso fazer em menos bytes).
Golfe:
Ungolfed c / explicação:
Tão perto de Retina! :(Sim, bata em Retina!fonte
Javascript (ES6),
511500496 bytesUngolfed e comentou
Casos de teste
O trecho abaixo mostrará todos os casos de teste de verdade e falsidade.
Mostrar snippet de código
fonte