Uma sequência regular é assim:
Hello,IAmAStringSnake!
E uma cobra de corda é algo como isto:
Hel
l rin
o,IAmASt g
S
!ekan
Sua tarefa
As cobras de corda são perigosas, portanto, você deve criar um programa que use uma cobra de corda como entrada e a produz como uma corda regular.
Especificações
- A entrada pode ser uma sequência multilinha ou uma matriz de sequências.
- Cada linha da entrada será preenchida com espaços para formar uma grade retangular.
- Os personagens da cobra só podem se conectar a personagens adjacentes acima, abaixo, esquerda ou direita deles (assim como no jogo Cobra). Eles não podem ficar na diagonal.
- Os caracteres de cobra nunca estarão adjacentes a outra parte da serpente, apenas os caracteres conectados.
- O primeiro caractere da string é o caractere final com a menor distância de Manhattan do canto superior esquerdo da grade de entrada (ou seja, o número mínimo de movimentos necessários para uma cobra ir diretamente do caractere final para o canto superior esquerdo canto). Ambas as extremidades nunca terão a mesma distância.
- A cadeia pode conter qualquer caractere ASCII entre os pontos de código 33 e 126, inclusive (sem espaços ou novas linhas).
- A sequência terá entre 2 e 100 caracteres.
- O menor código em bytes vence.
Casos de teste
(Grade de entrada, seguida pela sequência de saída)
Hel
l rin
o,IAmASt g
S
!ekan
Hello,IAmAStringSnake!
----------
Python
Python
----------
P ngPu Code
r i z d G
o m z n o
gram lesA lf
ProgrammingPuzzlesAndCodeGolf
----------
~ zyx tsr XWVUTSR
}|{ wvu q Y Q
! p Z `ab P
"#$ 6789:; o [ _ c O
% 5 < n \]^ d N
('& 432 = m e M
) 1 > lkjihgf L
*+,-./0 ? K
@ABCDEFGHIJ
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
----------
tSyrep
r p
in Sli
g Sile
Snakes n
Ser ylt
a eh ilS
fe w t
emo h
Sre
SlipperyStringSnakesSilentlySlitherSomewhereSafe
Respostas:
APL, 55 bytes
Esta função usa uma matriz de caracteres com a string snake.
Exemplo:
Explicação:
(,⍵≠' ')/,⍳⍴⍵
: obtém as coordenadas de todos os não espaços(⊂0 0)
: começa em (0,0) (que é uma coordenada inválida){
...}
: siga a cobra, dada a posição e a cobra:1<⍴⍵:
: se houver mais de 1 elemento restante:∆←⍵~⍺
: remova a posição atual da cobra e guarde-a∆
.+/¨|⍺-∆
: encontre a distância entre a posição atual e cada ponto no resto da cobra∆[⊃⍋...
] `: obtenha o ponto mais próximo da cobra∇
: execute a função novamente, com o ponto mais próximo como o novo ponto atual e a cobra encurtada como a nova cobra.⍺,
: adicione a posição atual ao resultado dessa⋄⍺
: caso contrário, basta retornar a posição atual1↓
: solta o primeiro item do resultado (que é a posição (0,0))⍵[
...]
: obtenha esses elementos de ⍵, nessa ordemfonte
JavaScript (ES6) + SnakeEx , 176 bytes
Lembra do SnakeEx? Bom, porque eu também não! Sugestões de golfe são bem-vindas.
fonte
MATL , 80 bytes
Graças a @LevelRiverSt pela correção
A entrada é como uma matriz 2D de caracteres, com linhas separadas por
;
. Os casos de teste neste formato sãoExperimente online!
Explicação
As coordenadas de cada caractere não espacial são representadas por um número complexo. Para cada caractere atual, o próximo é obtido como o mais próximo (diferença absoluta mínima de suas coordenadas complexas).
Para determinar o caractere inicial, os dois pontos de extremidade precisam ser encontrados. Isto se faz do seguinte modo. Um terminal é um caractere não espacial que possui exatamente um vizinho não espacial. O número de vizinhos é obtido por convolução 2D com uma máscara adequada. O ponto inicial é o ponto final cuja coordenada complexa possui a menor soma de partes reais e imaginárias; ou seja, é o mais próximo na distância de Manhattan ao número complexo 0 ou equivalente a 1 + 1j, que é a coordenada complexa do canto superior esquerdo.
fonte
The initial point is the endpoint whose complex coordinate has the least absolute value
Cuidado: Distância euclidiana! = Distância de Manhattan. por exemplo, o ponto 7 + 7j tem a distância euclidiana 9.8994 e a distância 14. de Manhattan. 10j é mais distante pela distância euclidiana, mas consideravelmente mais perto pela distância de Manhattan. Fora isso, ótimo conceito!C
198190179180181 bytesEdit: Utilizou a dica pelo user81655 e removeu os parênteses no operador ternário, obrigado! Também mudei o teste complicado (S & 1) para uniformidade para o S% 2 mais apropriado (e mais curto!).
Edit2: Usando o * a estilo de endereçamento pesadamente, fiquei cego às otimizações óbvias na definição de S, ou seja, substituindo * (a + m) por um [m] etc. Em seguida, substitui S por T, o que essencialmente metade do que S faz. O código agora também aproveita o valor de retorno do putchar.
Edit3: Corrigido o erro que existe desde o início, os critérios de parada de pesquisa em Manhattan a <b + m estão corretos apenas se a já tiver sido diminuída. Isso adiciona 2 bytes, mas um é recuperado, tornando a definição de m global.
Edit4: Meu golfe passou o mínimo e está indo no caminho errado agora. Outra correção de bug relacionada à pesquisa em Manhattan. Originalmente, eu tinha verificações de ligação e, sem elas, a pesquisa continua por grandes matrizes de entrada (em torno de 50x50) além da matriz b. Portanto, essa matriz deve ser expandida para pelo menos duas vezes o tamanho anterior, o que adiciona mais um byte.
Ungolfed e explicou:
fonte
a[1]
,a[-m]
etc, e tornem
global -m=103;main()
.C, 272 bytes
Veja a fonte de @ Zunga. Agora olhe para o meu. Deseja saber como obtive os 91 bytes extras?
Ungolfed:
fonte
Python (2 e 3),
640 624 604 583 575 561 546538 bytesEu ainda sou um n00b de golfe, então isso é um pouco grande.
Edit: Obrigado a @porglezomp pelas sugestões! Não removi todos os operadores 'e', pois isso quebraria o Python 3.
Edit2: Obrigado a @Aleksi Torhamo pelo comentário sobre o isspace (). A redução resultante compensa a correção de bug que eu coloquei. Também graças ao anonymous pelo destaque da sintaxe!
Edit3: Obrigado a mbomb007 por mais alguns bytes.
E aqui está a minha versão pré-golfe
fonte
S=lambda s:s.isspace()
e fazendo emS(s)
vez des.isspace()
.and
para<
, já quef() < g() < h()
é o mesmo queg = g(); f() < g and g < h()
em termos de efeitos colaterais (curto-circuito das cadeias de comparação), e você está ignorando o resultado das comparações de qualquer maneira.m[(x,y)]=
é o mesmo que o menorm[x,y]=
S=str.isspace
S
e o uso<'!'
em todas as ocorrências podem ter o mesmo tamanho, possivelmente abrindo uma oportunidade para economizar mais. Mudandoif 1-S(v[x]):
paraif(v[x]<'!')<1:
, por exemplo. E talvez você possa remover alguns parênteses nas comparações posteriores fazendo dessa maneira.JavaScript (ES6), 195
Veja a explicação dentro do snippet de teste
Teste
fonte
););}
necessários?for
cabeçalho, onde são necessários dois pontos. O segundo é o delimitador dofor
corpoLua,
562535529513507504466458 BytesDe longe, o meu golfe mais massivo no momento,
acho que ainda posso cortar 100 bytes, nos quais trabalharei, mas publicá-lo como resposta, pois já levou algum tempo :).Eu estava certo, reduzi mais de 100 bytes! Não acho que haja muito espaço para melhorias.essa função deve ser chamada com uma matriz 2D contendo um caractere por célula.
Economizou 40 bytes ao trabalhar com @KennyLau , graças a ele!
Woohoo! Menos de 500!
Ungolfed
As explicações virão assim que eu terminar de jogar isso, por enquanto, emprestarei uma versão legível deste código-fonte: D Aseguir, as explicações!Editar: não atualizado com a modificação mais recente, ainda jogando golfe antes da atualização. O mesmo vale para as explicações
Então, aqui estão algumas explicações detalhadas sobre como este programa funciona.
Primeiro de tudo, vamos considerar o loop rotulado
a
, que permite encontrar o final mais próximo do canto superior esquerdo. Ele funcionará para sempre se não houver fim, mas isso não é um problema: D.Em uma grade 4x4, aqui estão as distâncias das cobras (esquerda) e a ordem em que elas são vistas (direita)
Para cada personagem, para ser o fim, é necessário verificar duas condições: - Não ser um espaço - Estar cercado por exatamente 3 espaços (ou exatamente 1 não espaço)
Essas condições são verificadas no seguinte trecho de código
Verificar se o char não é um espaço é alcançado pela expressão
m[i][j]~=s
.Verificando se você está cercado por apenas 1 não espaço, obtém-se as seguintes condições para o ambiente, isso pode ser escrito como
E finalmente, se todas as opções acima forem avaliadas como verdadeiras, o ternário retornará o que está no último
and
->m[i][j]
. Senão, deixamos porr
definir :)Agora que temos a cabeça da cobra, vamos até o outro extremo! A iteração da cobra é alcançada principalmente pelos seguintes ternários aninhados:
Nós redefinimos
i
ej
, ao mesmo tempo, para evitar a necessidade de manequins para armazenar os valores antigos. Ambos têm exatamente a mesma estrutura e usam condições simples; portanto, eu os apresentarei na forma de aninhadosif
, deve permitir que você os leia mais facilmente. :)Pode ser traduzido para:
Teste-o!
Aqui está o código que eu uso para executar isso, você pode testá-lo online copiando e colando.
fonte
Lua, 267 bytes
Lua 5.3 é necessária.
Uso:
fonte
Python 3,
245243241236 bytess
é a sequência de entrada,n
é a saída impressa em stdout:Edit: Obrigado a @Cees Timmerman por salvar 5 bytes!
fonte
c>' 'and
eprint n
em Python 2.if
vez deelif
?s
variável Qwerp-Derp é uma sequência de múltiplas linhas ; o último caractere da string deve ser uma nova linha (isto é necessário para passar noPython
caso de teste)Python, 537
Minha solução inicial:
Compactou um pouco, mas deixou como um método:
fonte
Java 7,
927924923 bytesOk, demorou um pouco .. Em algumas linguagens de programação, não importa se sua matriz xey está fora dos limites de uma matriz 2D, mas com Java será lançada
ArrayIndexOutOfBoundsExceptions
, então tudo deve ser verificado.Primeiro, determino o ponto de partida e, em seguida, uso um método recursivo para criar a string a partir daí. Além disso, eu uso uma lista para acompanhar as coordenadas que já encontrei, para que ela não entre em loop (resultando em StackOverflowException).
Esta é provavelmente a resposta mais longa que eu postei até agora, mas, embora algumas partes possam ser jogadas de golfe, não acho que esse desafio possa ser muito mais curto em Java. Java simplesmente não é adequado para seguir um caminho em uma grade. No entanto, foi um desafio divertido descobrir. :)
Casos não testados e de teste:
Experimente aqui.
Resultado:
fonte
PHP,
199184182 bytesainda pode ter um pouco de potencial de golfe
recebe entrada como string de múltiplas linhas na linha de comando, espera quebras de linha no estilo linux.
Corra
php -r '<code>' '<string>'
; escapar quebras de linha.demolir
fonte
C #, 310
(Editar: correção de bug)
Uma função com um parâmetro de sequência multilinha, retornando uma sequência.
Incluindo o solicitado
using
na contagem de bytes.Esta é uma portabilidade da minha resposta javascript.
Teste em ideone
Com espaços
fonte
Python 2, 251 bytes
Ou, se desejar novas linhas de frente em seus casos de teste, 257 bytes:
Passa em todos os casos de teste.
Resulta em:
fonte
b.append(...)
porb+=[...]
edef n(x,y):return ...
comn=lambda x,y:...
' '
.~-x
vez dex-1
, você não precisará usar parênteses.Japonês
-P
, 106 bytesExperimente online!
É ... hum ... uma abominação.
Descompactado e como funciona
Um ponto notável é que usei a precedência do operador entre operadores de atribuição e vírgula em JS, para empacotar algumas linhas e manter o atalho
@
(XYZ{
) utilizável.fonte