Às vezes, ao escrever o código do cérebro, você sente necessidade de prolongá-lo mais do que o necessário para incentivar a depuração. Você poderia fazer isso apenas colocando um ><
lá, mas que graça é essa? Você precisará de algo mais e menos NOPey para confundir qualquer pessoa que esteja lendo seu código.
Introdução rápida ao Brainfuck
Brainfuck é uma linguagem de programação esotérica criada em 1993 por Urban Müller, e notável por seu extremo minimalismo. (Wikipedia)
Brainfuck é uma linguagem baseada em oito comandos: +-><,.[]
. O código é executado em algo como uma máquina de Turing: uma fita infinita na qual os valores podem ser alterados. Neste desafio, focaremos nos quatro primeiros:
+ increment the value at the pointer
- decrement the value at the pointer
> move the pointer right
< move the pointer left
Brainfuck NOPs
Um NOP com ação cerebral é uma sequência de caracteres com ação cerebral que, quando executados a partir de qualquer estado, não levam a nenhuma alteração no estado. Eles consistem nos quatro caracteres mencionados acima.
O desafio
O desafio é escrever um programa ou função que, quando executado, gere um NOP aleatório com o tamanho de um determinado comprimento.
Entrada
Você receberá como entrada um inteiro par não-negativo n
. (NOPs são impossíveis para ímpares n
).
Saída
Você produzirá um NOP aleatório do tamanho do cérebro n
.
Regras
- A definição de NOP: quando a saída do programa é inserida em qualquer ponto do programa, o comportamento do programa não deve mudar de forma alguma. Em outras palavras, ele não deve alterar o estado do intérprete.
- Observe que, por exemplo
+>-<
está incorreto, pois altera os valores das duas células sem alterá-los novamente. Teste sua solução antes de postar. - Observe também que
+>-<->+<
é um NOP que não pode ser reduzido a nada apenas com a remoção><
<>
+-
-+
. Portanto, você não pode usar um algoritmo que apenas os insere.
- Observe que, por exemplo
- Todo NOP válido do comprimento
n
deve ter uma chance diferente de zero de aparecer na saída. A distribuição não precisa ser uniforme, no entanto. - O intérprete do cérebro em questão tem uma fita duplamente infinita de células de precisão arbitrárias. Ou seja, você pode ir infinitamente para as duas direções e aumentar / diminuir cada célula indefinidamente.
- O programa deve terminar dentro de 1 minuto para
n
= 100 na minha máquina, para não gerar todos os NOPs possíveis e escolher um. - Se você receber uma entrada inválida (não inteiro, negativo, ímpar, etc.), poderá fazer o que quiser, incluindo falha.
Pontuação
Isso é código-golfe , então a resposta mais curta em bytes vence.
Exemplos
Aqui estão todas as saídas válidas para n
= 4:
++-- +-+- +--+ --++ -+-+ -++-
>><< ><>< ><<> <<>> <><> <>><
><+- ><-+ <>+- <>-+
>+-< >-+< <+-> <-+>
+><- -><+ +<>- -<>+
+->< -+>< +-<> -+<>
Aqui estão algumas saídas possíveis para n
= 20:
+>>->+<->-<<<->>++<<
>+>-<+<->+-<>->+<-<+
+--+-++--++-+--+-++-
>>>>>>>>>+-<<<<<<<<<
fonte
+-<>
como você pediu:a
.
tem um efeito colateral,,
substitui um valor que não pode ser recuperado sem o uso de[]
. Mas[]
acabará definindo um valor para zero. Isso também substitui um valor (portanto, precisaríamos de outro[]
para recuperá-lo), a menos que possamos ter certeza de que a célula afetada era zero no início. No entanto, teríamos que procurar uma célula com algo parecido[>]
e é impossível retornar com segurança à posição de onde viemos.Respostas:
CJam,
6259 bytesObrigado a nhahtdh por salvar 3 bytes.
Como não há requisito para uma distribuição específica, desde que cada operação não apareça com probabilidade finita, podemos simplificar muito isso simplesmente gerando uma string contendo um número equilibrado de
-+
e<>
, respectivamente, testando se é um NOP e classificando-o se não é.Obviamente, para entradas mais longas, isso quase sempre resultará em uma saída classificada, mas você pode testar o código com alguma entrada
8
para ver se ele pode, em princípio, produzir qualquer NOP do comprimento especificado.Experimente online.
fonte
CJam,
118116 bytesIsso ficou um pouco fora de controle ... especialmente a segunda metade parece que deve ser muito jogável.
Teste aqui.
Isso lida com
N = 100
praticamente instantaneamente. Eu não tenho tempo para escrever a repartição completa do código agora, então aqui está o algoritmo:<
e>
com comprimento aleatório (par) entre0
eN
inclusive."<>><"
torna-se[0 '< -1 '> 0 '> 1 '< 0]
.N
.+-
à sequência de uma posição aleatória.Feito. Isso se baseia na observação de que:
<
e>
retornar a cabeça da fita à posição original.Ao distribuir quantidades aleatórias, mas equilibradas, de
+
s e-
s entre todos os locais onde a cabeça da fita está em uma determinada célula, garantimos que encontramos todos os NOP possíveis.fonte
Mathematica, 350 bytes
Tempo demais? Sim. Eu me importo? Não até outra pessoa postar uma resposta válida.
fonte
+
.+
--
e<
->
pares até que um passa a ser um NOP. Metade disso é tomada por um simples intérprete de AM.Python 3 , 177 bytes
Experimente online!
Eu usei o código da resposta de Bubbler para a simulação BF.
fonte
Python 3 , 163 bytes
Experimente online!
Programa completo que imprime resultados para STDOUT. A linha que executa o código BF pode ser jogável.
Adotou a abordagem de Tyilo; se o código BF gerado não for um NOP, descarte-o completamente e volte a
'+-'
repetir.fonte
JavaScript (Node.js) , 160 bytes
Experimente online!
fonte
Wolfram Language (Mathematica) , 224 bytes
Experimente online!
Aqui está a versão sem golfe (ou melhor, pré-golfe):
Primeiro escolhemos um número aleatório de
<
's e>
' para usar e geramos uma lista aleatória com um número igual de cada.Para preencher o restante dos caracteres, escolhemos uma posição na qual adicionar a
+
, em seguida encontramos uma posição em que o ponteiro aponta para o mesmo local e adicionamos uma-
lá.Repita até que a lista tenha comprimento
n
e especifique o resultado.fonte