`:_64/"32}
,` (3 :=-{
"`{"; _v2$ ;`3
"`".:@ ; ".5(`3.
< "" `^`;>
Outra colaboração com o @ MartinBüttner e no lado mais insano do espectro do labirinto - pela primeira vez, temos todos os quatro ^>v<
no mesmo programa. Experimente online!
Explicação
O algoritmo geral, que roda em loop, é o seguinte:
1. Read a char
2. If EOF:
3. Move all digits from auxiliary stack to main
4. Output all digits on main stack
5. Halt
Otherwise:
6. If char is a letter (c >= 64):
7. If random turns left:
8. Output char XOR 32
Otherwise:
9. Output char
Otherwise:
10. Shift char to auxiliary stack
11. If char is space (c-32 == 0):
12. Pull char back from auxiliary stack
13. Output underscore
Otherwise:
14. Continue loop
Para manter a explicação compacta, veja a seguir como cada parte do programa corresponde ao pseudocódigo acima:
Aqui estão as partes interessantes.
Obtendo aleatoriedade no labirinto
Existe apenas uma maneira de obter aleatoriedade no Labyrinth, e é quando o IP tenta avançar, mas 1) não há caminho para a frente nem para trás e 2) há caminhos disponíveis à esquerda e à direita. Nesse caso, o IP escolhe aleatoriamente entre as rotas esquerda e direita.
Isso só é possível usando os ^>v<
operadores, que exibem n
e deslocam a linha / coluna n
em 1. Por exemplo, o programa ( Experimente online! )
" 1
""v!@
2
!@
gera 1 ou 2 aleatoriamente, uma vez que a v
coluna é deslocada com deslocamento 0 (ou seja, a coluna em que o IP está) por 1, produzindo
"
""1!@
v
2!@
O IP está voltado para a direita e tenta avançar (o topo da pilha é zero), mas não pode. Ele também não pode se mover para trás, portanto escolhe aleatoriamente entre esquerda ou direita.
Truques de golfe
O programa inicia a partir do primeiro caractere na ordem de leitura, que você notará na verdade na etapa 6. No entanto, saltar de uma pilha de labirinto vazia produz 0, portanto ocorrem as etapas 10 e 14, deslocando um zero para a pilha auxiliar, o que é efetivamente um no-op.
A pilha principal fica efetivamente vazia após cada iteração, o que nos permite alterar o layout do código usando >
e <
nos zeros implícitos na parte inferior. Ele >
envolve a linha inferior para que o IP se mova da parte inferior direita para a parte inferior esquerda, e <
a linha é deslocada para trás. O IP então move-se alegremente para cima na coluna esquerda para continuar o loop.
Dígitos no labirinto estalam n
e empurram 10*n + <digit>
. Além disso, os caracteres são tomados no módulo 256 antes de serem produzidos. Colocar esses dois juntos nos permite gerar 95 (sublinhado) fazendo `33
32 (espaço), o que funciona porque -3233 % 256 = 95
. Embora existam outras maneiras de transformar 32 em 95 ( ;95
sendo a mais fácil), trabalhar com um número negativo aqui nos permite compactar um pouco o código com as curvas à esquerda.