Dicas para jogar golfe no espaço em branco

14

Que dicas gerais você tem para jogar golfe no Whitespace? Estou procurando idéias que possam ser aplicadas a problemas de código-golfe e que também sejam pelo menos um pouco específicas do espaço em branco (por exemplo, "remover comentários" não é uma resposta).

Poste uma dica por resposta.

Loovjo
fonte
82
Remova espaço em branco desnecessário.
KSFT
1
s / [^ [: space:]] // g
Digital Trauma

Respostas:

11

Não tenho muita certeza se essa é uma pergunta de piada ou não, então espero não ser ridicularizada por levar a sério, mas ...

Dica 1: não termine seu programa

A especificação diz que um programa deve terminar com três feeds de linha [LF][LF][LF], onde o primeiro é o IMP de controle de fluxo e os próximos dois são o comando quit, mas muitos intérpretes simplesmente executam seu código sem o final apropriado. Economiza 3 caracteres em qualquer programa.

theonlygusti
fonte
6

Dica 2: use o heap o mínimo possível

Eu costumava usar muito o Heap para contar meus loops, mas percebi que era realmente extremamente ineficiente; primeiro pressionando um endereço, obtendo a contagem atual, recebendo / adicionando um, pressionando novamente o endereço etc.

Agora, apenas empurro um valor na pilha para atuar como contador de loop e, em seguida, uso o [Space][LF][Tab]comando swap para retornar quando necessário. É preciso muito trabalho em torno, mas quando você o obtém, pode realmente reduzir sua contagem de caracteres.

theonlygusti
fonte
5

Use endereços de heap arbitrários

Muitos intérpretes permitem que você leia / grave em endereços de heap arbitrários, em vez de começar em 0 ou 1 e fazer a contagem. Você pode duplicar um valor de pilha existente (3 bytes) para usar como endereço, em vez de enviar um novo valor (mínimo de 4 bytes)

Ephphatha
fonte
+1. Observe que isso se aplica apenas a endereços de heap não negativos. Portanto, se o topo da pilha for um número inteiro negativo, você não poderá usá-lo como endereço de pilha.
Kevin Cruijssen
5

A sequência vazia é um rótulo válido

[LF][Space][Space][LF](Controle de fluxo - marque com o rótulo '') cria um rótulo vazio que é um destino válido para saltos ou chamadas de sub-rotina. Isso economiza um byte ao declarar o rótulo e um byte toda vez que é chamado.

( Observado na resposta em branco para implementar uma máquina da verdade )

Ephphatha
fonte
5

Abaixe todos os caracteres por um valor fixo e adicione-o logo antes de imprimir em um loop

Agradecemos a @LukStorms , que usa uma abordagem semelhante em sua resposta para o desafio Hello World .

( STNusado para espaço, tabulação e nova linha, respectivamente.)

Pressionar os valores para as letras é sempre 11 bytes (ou seja, pressionar o valor 65 para o caractere 'A' é SSSTSSSSSTN; pressionar o valor 122 para o caractere 'z' é SSSTTTTSTSN). Quando você deseja gerar uma grande quantidade de texto, isso pode ser caro. Em vez disso, você pode diminuir os valores de todos os caracteres que deseja imprimir em um valor fixo e, em seguida, no loop para imprimi-los, adicione esse valor fixo.

Isso pode ser feito com o seguinte código (vamos assumir que o valor fixo é 100 neste caso):

  1. Empurre todos os valores para os caracteres (menos o valor fixo 100) na ordem inversa
  2. NSSN (Crie um Label_0; basicamente iniciando o loop)
    1. SSSTTSSTSSN (Empurre o valor fixo 100)
    2. TSSS (Adicione os dois principais valores da pilha)
    3. TNSS (Pop e imprima o valor agora correto como caractere)
    4. NSNN (Salte para Label_0; vá para a próxima iteração do loop)

Isso interromperá o programa com um erro (o que é permitido de acordo com a meta ) assim que ele tentar fazer o Add ( TSSS) sem mais nada na pilha. Eu usei isso para jogar com esta resposta minha (consulte os itens 5 e 6 de Coisas que fiz para diminuir a contagem de bytes ).

Se uma quantidade fixa de 100 é a abordagem mais curta depende do que você está imprimindo. O @LukStorm, por exemplo, usou 107 em sua resposta Hello World.

Observe que copiar o valor superior ( SNS) para dois dos mesmos caracteres adjacentes (como o lin Hello) ou copiar valores de outra posição ainda pode ser usado além disso para obter mais bytes.

Kevin Cruijssen
fonte
4

Saltar para etiquetas indefinidas termina o programa (em alguns intérpretes)

Isso começa a entrar no comportamento específico da implementação, mas acredito que isso seja permitido .

O TIO (e possivelmente outros intérpretes? Não funcionam pelo menos em ideônos) interromperá a execução quando for feita uma tentativa de pular para um rótulo que não existe. Se você precisar fazer uma comparação para interromper um loop, isso permitirá que você salve bytes, não declarando o rótulo de interrupção. (Veja meu comentário em Imprimir texto invisível para um exemplo.)

Ephphatha
fonte
4

O valor 0 pode ser declarado como um número sem dígitos binários

O tutorial de espaço em branco menciona que os números podem ter qualquer número de bits / dígitos binários. Isso significa que um número sem bits (além do bit de sinal necessário) é uma representação válida do valor 0. [Space][Space][Space][LF]e [Space][Space][Space][Space][LF]ambos empurram o valor 0 para a pilha, mas o primeiro é um byte mais curto.

Ephphatha
fonte
0

Copiar números inteiros anteriores pode ser mais curto do que criar novos

( STNusado para espaço, tabulação e nova linha, respectivamente.)

STS+ Argumento número pode ser utilizado para copiar o n th produto na pilha (dado pelo argumento) para o topo da pilha . Em alguns casos, isso pode ser usado para salvar bytes.

Por exemplo, nesta resposta minha , expliquei no quarto item de Coisas que fiz para diminuir a contagem de bytes, como copiar o primeiro valor (indexado a 0) ( STSSTN) é menor do que pressionar 12 para criar o caractere 'p' ( SSSTTSSN) na parte "pop"da saída. (NOTA: Eu uso o valor 12 em vez de 112 para o caractere 'p', porque apliquei essa outra dica de diminuir todos os valores por um valor fixo, que adicionamos antes de imprimir os caracteres no loop .)

Kevin Cruijssen
fonte