Labirinto , 28 25 24 23 22 bytes
" >
?!?:|}\{@
@\?"":)!
Isso foi divertido louco! :) Esse é de longe o programa Labirinto mais densamente compactado que escrevi até agora. Eu tinha tantas versões em 20 e 21 bytes que quase funcionou que ainda estou duvidando que isso seja ótimo ...
Isso recebe a entrada como uma lista de números inteiros positivos (com um delimitador arbitrário) e imprime o resultado em STDOUT como números inteiros delimitados por alimentação de linha.
A busca por 20/21 bytes: verifiquei todos os programas no formulário
" XX
?!?X}\{@
@\?XX)!
onde X
existe qualquer caractere razoável por força bruta, mas não encontrou soluções válidas. É claro que isso não significa que não exista uma solução mais curta, mas não é possível forçar programas de 20 bytes sem uma quantidade razoável de suposições em sua estrutura.
Explicação
(A explicação está um pouco desatualizada, mas ainda não estou convencida de que a solução seja ótima, então esperarei atualizando isso.)
Portanto, normalmente os programas de labirinto devem parecer labirintos. Enquanto o ponteiro de instruções estiver em um corredor, ele seguirá esse corredor. Quando o IP atinge qualquer tipo de junção, a direção é determinada com base no valor superior da pilha principal do labirinto (o labirinto possui duas pilhas, com uma quantidade infinita de zeros na parte inferior). Isso normalmente significa que qualquer loop não trivial será muito caro, porque se você tiver células que não sejam de parede em todo o lugar, tudo será uma junção e, na maioria dos casos, a parte superior da pilha não terá o valor certo para o IP. para seguir o caminho que você gostaria que ele seguisse. Então, o que você faz é aumentar os loops para que eles tenham um todo no centro, com apenas um ponto de entrada e saída bem definido cada.
Mas desta vez eu tive muita sorte e tudo se encaixou tão bem, que eu pude esmagar tudo em um grande grupo. :)
O fluxo de controle começa no _
sul. O _
empurra um zero para a pilha principal. Isso pode parecer um não operacional, mas isso aumenta a profundidade da pilha (não implícita) da 1
qual precisaremos mais tarde.
?
lê um número inteiro de STDIN. Se não houver mais números inteiros a serem lidos, isso empurrará zero. Nesse caso, o IP continua se movendo para o sul e @
finaliza o programa imediatamente (porque a lista de entrada está vazia). Caso contrário, o IP vira para o leste.
Agora estamos entrando em um loop muito fechado com dois pontos de saída:
!?;
\?
;
!
imprime o número inteiro de volta para STDOUT, deixando apenas um zero na pilha. O IP continua se movendo para o leste e ?
lê o próximo número inteiro. Se isso for diferente de zero, vire à direita e seguimos para o sul. ?
lê outro (o próximo índice par). Novamente, se for diferente de zero, vire à direita e seguimos para oeste.
Em seguida, \
imprime um avanço de linha sem alterar a pilha, por isso vimos outra à direita, movendo para o norte. !
imprime o próximo número inteiro do mesmo índice. Como agora há pelo menos um número inteiro de índice ímpar (positivo) na pilha, continuamos girando para a direita e o loop se repete.
Uma vez que qualquer um desses ?
itens chegue ao final da lista, eles pressionam um zero e passam direto para o correspondente ;
, que descarta esse zero.
No caso de haver apenas um elemento na lista, estamos prontos (porque o imprimimos imediatamente), para que o IP continue se movendo para o leste até o final @
, novamente encerrando o programa (imprimindo um avanço de linha no caminho).
Caso contrário, também precisamos imprimir os números inteiros do índice ímpar. Nesse caso, os dois caminhos (dos dois pontos de saída do primeiro loop) se fundem no meio "
, virando o leste nos dois casos.
_
empurra um zero para evitar virar à esquerda no @
e ;
descarta esse zero. Agora entramos em um novo loop:
"}
""
O IP digita isso na célula inferior esquerda, movendo-se para o norte, contornando o loop no sentido horário. O }
deslocamento da parte superior da pilha principal para a pilha auxiliar. Embora ainda exista um elemento na pilha, o IP continua a funcionar. Depois que tudo foi deslocado para a pilha auxiliar (e revertida no processo), o IP continua se movendo para o leste, entrando no último loop:
\{@
#!
\
imprime um avanço de linha novamente, {
move um item da pilha auxiliar de volta para principal. Se esse ainda fosse um item da lista, será positivo e o IP mudará para o sul, onde o item é impresso !
. Em seguida, #
empurra a profundidade da pilha (e agora é aqui que a inicial _
é importante, pois isso #
garante uma profundidade positiva da pilha), para que o IP ainda vire à direita, através da \
e {
novamente.
Depois de imprimir tudo, {
extrair um zero da parte inferior da pilha auxiliar, o IP continuará no leste e @
encerrará o programa.