Implementar uma máquina da verdade


148

Uma máquina da verdade (os créditos são atribuídos a esse cara por ter sido apresentada) é um programa muito simples, projetado para demonstrar o fluxo de E / S e controle de um idioma. Aqui está o que uma máquina da verdade faz:

  • Obtém um número (0 ou 1) de STDIN.

  • Se esse número for 0, imprima 0 e termine.

  • Se esse número for 1, imprima 1 para sempre.

Desafio

Escreva uma máquina da verdade, conforme descrito acima, no seu idioma de escolha. A máquina da verdade deve ser um programa completo que siga estas regras:

  • receba informações do STDIN ou de uma alternativa aceitável
    • Se o seu idioma não puder receber a entrada do STDIN, ele poderá receber a entrada de uma variável codificada ou um equivalente adequado no programa
  • deve enviar para STDOUT ou uma alternativa aceitável
    • Se o seu idioma for incapaz de gerar os caracteres 0ou 1, byte ou E / S unária, é aceitável.
  • quando a entrada é 1, ela deve imprimir continuamente 1se parar somente se o programa estiver morto ou ficar sem memória
  • a saída deve ser apenas a 0seguida por uma ou nenhuma nova linha ou espaço ou 1s infinitos com cada um 1seguidos por uma ou nenhuma nova linha ou espaço. Nenhuma outra saída pode ser gerada, exceto a saída constante do intérprete do seu idioma que não pode ser suprimida (como uma saudação, códigos de cores ANSI ou recuo). Seu uso de novas linhas ou espaços deve ser consistente: por exemplo, se você optar por gerar uma nova 1linha depois que tudo 1s deve ter uma nova linha após eles.

  • se e somente se seu idioma não puder terminar em uma entrada 0dele, é aceitável que o código insira um loop infinito no qual nada é emitido.

Por se tratar de um catálogo, os idiomas criados após esse desafio podem competir. Observe que deve haver um intérprete para que o envio possa ser testado. É permitido (e até encorajado) escrever esse intérprete para um idioma anteriormente não implementado. Fora isso, todas as regras padrão do devem ser obedecidas. Os envios na maioria dos idiomas serão pontuados em bytes em uma codificação preexistente apropriada (geralmente UTF-8).

Catálogo

O snippet de pilha na parte inferior desta postagem gera o catálogo a partir das respostas a) como uma lista da solução mais curta por idioma eb) como uma tabela geral de líderes.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

## Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

## Perl, 43 + 2 (-p flag) = 45 bytes

Você também pode transformar o nome do idioma em um link que será exibido no snippet:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


Podemos supor que o programa pare quando o processador terminar de executar o código escrito, para uma entrada de código de máquina?
lirtosiast

3
Supondo que qualquer comportamento seja bom para todas as entradas inválidas?
Cruncher

3
@Cruncher Sim, as únicas entradas que você deve esperar para obter são 0 e 1.
um Spaghetto

4
O catálogo está com bork.
Addison Crump #

2
O catálogo parece considerar Bfe bfser idiomas diferentes.
Mooing Duck

Respostas:


189

Hexagonia , 6 bytes

Isso foi surpreendentemente complicado, e não estou convencido de que seja ideal ...

<.@!$?

Depois de preencher e desdobrar o código, isso representa a seguinte grade hexadecimal:

insira a descrição da imagem aqui

Isso usa um fluxo de controle semelhante ao meu recente programa de gato sem erros , movendo-se ao longo de antiagonais. Para conseguir isso, começamos desviando o ponteiro de instrução (IP) para a esquerda, onde o caminho roxo passa pelo canto inferior esquerdo.

?lê a entrada como um número inteiro. !imprime de volta. .é apenas um não-op. Agora o canto da grade atua como um ramo:

Se a entrada foi 0, o IP continuará no caminho vermelho, que simplesmente encerra o programa @.

Se a entrada foi 1, o IP continuará no caminho verde. Novamente, .é apenas um não-op, mas $é o equivalente ao trampolim de Befunge: pula a próxima instrução. Após a quebra, a próxima instrução seria a ?, mas devido à $execução, na verdade, continua no caminho azul, começando com !a impressão de outra cópia da 1. Este loop que contém apenas !..$agora é repetido indefinidamente.

Estudo do fluxo de controle em hexag ...

Eu acredito que a solução acima é ótima. Eu escrevi um forcer bruto, que verifica todos os programas Hexagony de 6 bytes, que contêm pelo menos um de cada um ?!@(o que é necessário; eu também verifiquei :e %substitui @para terminar com um erro de divisão por zero, mas isso também não ajudou). A verificação imprime todos os programas que a) produzem a 0na entrada 0e terminam eb) produzem pelo menos dois 1segundos (e nada mais) e não terminam dentro dos primeiros 60 ticks do programa (200 ticks para soluções de 5 bytes) . Duvido que qualquer solução válida levasse mais de 200 ticks para imprimir corretamente o primeiro 0ou o segundo 1em uma grade tão pequena, então acho que não perdi nenhuma solução em potencial.

A pesquisa não produziu nenhum resultado para 5 bytes, mas 57 resultados para 6 bytes (usando @; não é necessário terminar com um erro se pudermos resolver isso de maneira limpa na mesma quantidade de bytes). Desses 57, apenas 6 eram falsos positivos, que na verdade imprimiam apenas dois 1se entraram em um loop infinito sem imprimir mais. Uma solução foi listada duas vezes porque continha dois !comandos. Isso deixa exatamente 50 soluções válidas.

Há uma certa quantidade de degeneração entre as soluções em que um ou dois caracteres não são substanciais, por exemplo, porque eles são efetivamente não-ops de qualquer maneira. As soluções podem ser agrupadas em 23 conjuntos de programas genuinamente distintos (em alguns casos, há apenas uma única diferença de caracteres entre dois conjuntos, mas isso altera o fluxo de controle substancialmente, então eu os contei separadamente). Dois dos grupos até fazem uso de vários indicadores de instruções de uma maneira muito inesperada. Como eu nunca teria inventado a maioria dessas maneiras de usar os galhos e os espelhos, eles fazem um estudo muito interessante de que tipo de fluxo de controle é possível no Hexagony, e eu definitivamente aprendi alguns truques novos para futuros golfistas.

O fluxo geral de controle é quase sempre o mesmo: leia um número, imprima-o. Se 0encontrar um caminho para o @, se não continuar, continue !repetindo o tempo mantendo um valor de borda de 1. Há quatro exceções notáveis:

  • Uma solução (aquela com dois !) imprime dois 1s por iteração na grade, imprimindo cerca de duas vezes mais rápido que a maioria dos programas. Eu marquei este aqui com x2abaixo.
  • Algumas soluções (aquelas que contêm um o) substituem o 1por um 111(o código de caractere de o), para que eles imprimam três 1 s por iteração, fazendo-os imprimir cerca de três vezes mais rápido que a maioria dos programas. Eu os marquei com x3abaixo.
  • Duas soluções acrescentar um 1ao valor borda em cada iteração (assim 1-> 11-> 111-> ...). Eles imprimem muito rápido, mas acabam ficando sem memória. Eu os marquei com OoMabaixo.
  • Duas soluções entram em um loop muito apertado, que apenas oscila de um lado para o outro !, imprimindo em todos os outros ticks (em vez de em cada 5ª), o que os torna um pouco mais rápidos (e organizados). Eu os marquei com ><abaixo.

Então aqui está o zoológico inteiro:

#1                #5                #12                #19
?!/$.@            ?$!>$@            .?!/$@             |!|?$@  # ><
?!/$1@  # OoM     ?$!|$@            =?!/$@
?!/$=@                                                 #20
?!/$\@            #6                #13                $@.?<!
?!/$o@  # x3      ?/!<|@            .?/!$@             $@1?<!  # OoM
?!/$!@  # x2                        =?/!$@             $@=?<!
                  #7                                   $@o?<!  # x3
#2                ?\!<|@            #14
?!>$)@                              \!?__@             #21
?!>$1@            #8                                   _>_!?@
?!>$o@  # x3      ?<!>$@  # ><      #15
?!|$)@                              \_?!$@             #22
?!|$1@            #9                                   <!@.$?
?!|$o@  # x3      ?\$!@$            #16                <!@/$?
                                    \_?!_@             <!@=$?
#3                #10                                  <$@!$?
?!|)$@            ?~#!@)            #17                <.@!$?
?!|1$@            ?~#!@1            $$?\@!             </@!$?
?!|o$@  # x3                                           <=@!$?
                  #11               #18
#4                ?$)\@!            \$?\@!             #23
?_!<@>            ?$1\@!                               <<@]!?
                  ?$o\@!  # x3

A seguir, é apresentado um pequeno passo a passo de alguns grupos mais representativos. Vale a pena conferir especialmente os grupos 10 e 23. Existem muitos outros caminhos interessantes e, às vezes, complicados nos outros grupos, mas acho que o aborreci o suficiente no final disso. Para quem realmente quer aprender Hexagony, definitivamente vale a pena investigar, pois eles exibem ainda mais usos possíveis dos espelhos e $.

Grupo 1

Este não é muito mais elaborado do que minha solução original, mas os caminhos seguem em direções diferentes. Ele também permite o maior número de variações em uma única célula, pois o no-op mais à direita pode ser substituído por 5 comandos diferentes que ainda o tornam válidos sem alterar a estrutura:

insira a descrição da imagem aqui

Grupo 2

Este é bastante interessante, porque só se move horizontalmente. Depois de quebrar para o >, o IP reverte imediatamente, levando a ramificação no canto. Não é totalmente visível o diagrama, mas no caso de 1atravessarmos a primeira linha novamente, mas desta vez para trás. Isso também significa que encontramos ?novamente, que agora retorna 0(EOF). Isso é corrigido com )(incremento) para continuar imprimindo 1s. Isso também tem 5 variações, como )também pode ser 1ou o, e >também pode ser |:

insira a descrição da imagem aqui

Grupo 3

Este parece quase idêntico ao anterior, mas é confuso como o inferno. Até bater |e, em seguida, percorrendo a linha inferior ou superior, é a mesma coisa. Mas, no caso de um loop, o $agora salta sobre o ) sobre o espelho. Então, seguimos o caminho turquesa para a direita, agora atingimos o incremento, pulamos o @antes de voltarmos para o | novamente e depois voltamos para o caminho verde no topo.

insira a descrição da imagem aqui

Grupo 4

Eu pensei que este era particularmente bacana:

insira a descrição da imagem aqui

O _espelho no canto superior direito é inicialmente um no-op, então imprimimos com !e pressionamos o <. O 0caminho agora atinge o espelho horizontal e termina. O 1caminho segue uma trajetória realmente interessante: desvia, desce para o !, é redirecionado para a horizontal e depois volta para o ! novo . Em seguida, ele continua se movendo nessa forma de losango, imprimindo duas vezes por iteração (a cada terceiro tick).

Grupo 8

Esta é uma das duas soluções com um loop de impressão muito apertado:

insira a descrição da imagem aqui

Os <atos como o ramo. Depois de embrulhar duas vezes, 0acerta @. 1por outro lado, primeiro pula o ?, depois o >envia para o $novamente, de modo que pula o @. Em seguida, o IP passa pelo caminho turquesa, onde salta para frente e para trás entre >e <(envolvendo a borda no meio).

Grupo 10

Um dos dois grupos que usam outros indicadores de instruções, e é absolutamente lindo. A hexagonia possui 6 - cada uma começa em um canto diferente no sentido horário, mas apenas uma delas está ativa por vez.

insira a descrição da imagem aqui

Como sempre, lemos com ?. Agora ~é uma negação unária: transforma o 1em um -1. Em seguida, atingimos o #. Esta é uma maneira de alternar entre IPs: ele pega o valor atual do módulo 6 e alterna para o IP correspondente (os IPs são numerados 0no sentido horário). Portanto, se a entrada foi 0, o IP simplesmente permanece o mesmo e segue entediante para a frente !@. Mas se a entrada foi 1, então o valor atual é -1qual é 5 (mod 6). Então, mudamos para o IP que começa na mesma célula (o caminho verde). Agora #é um no-op e ?define a borda da memória como 0. )incrementos para !imprimir a 1. Agora batemos ~novamente para garantir que#ainda é um no-op (ao contrário de nos mudar para o IP 1 que encerraria o programa). É impressionante como tudo se encaixa nesse pequeno programa.

Grupo 22

Apenas para observar, esse é o grupo em que minha solução original está. Também é o maior grupo, porque o no-op pode estar em dois lugares diferentes e existem várias opções para o comando real (no-op efetivo).

Grupo 23

Este é o outro grupo usando vários IPs. De fato, este usa três IPs diferentes. O canto superior direito é um pouco confuso, mas vou tentar orientá-lo sobre isso:

insira a descrição da imagem aqui

Então, o começo que você já viu antes: <desvia o Nordeste, ?lê a entrada. Agora ]é outra maneira de mudar entre IPs: ele passa o controle para o próximo IP na ordem horária. Então, mudamos o controle para o caminho turquesa que (eu sei que é difícil de ver) começa no canto nordeste, indo para sudeste. Ele é imediatamente refletido no <modo que ele segue para o canto sudeste, indo para o noroeste. Ele também atinge o ]botão, então mudamos para o próximo IP. Este é o caminho cinza que começa no canto leste, indo para o sudoeste. Ele imprime a entrada e, em seguida, passa para o canto nordeste. <desvia o caminho para a horizontal, onde é refletido pelo outro < . Agora a mão direita<atua como um ramo: se a entrada foi 0, o IP se move para o nordeste e passa para o @. Se a entrada foi 1, o IP se move para o !, passa para a esquerda e para <onde é refletido ... agora no canto, volta para o !, é desviado pela direita <, refletida pela esquerda <e o caminho começa sobre...

Uma bagunça, mas uma bagunça linda. :)


Diagramas gerados com o incrível HexagonyColorer de Timwi .


55
Uau. apenas whoa.
Conor O'Brien

6
^ concordou. Tão legal ...
El'endia Starman

28
Cale a boca e aceite meu voto!
Mego

7
@ThomasOltmann Admito que esta resposta pressupõe algum conhecimento básico da linguagem. Se você está realmente interessado em aprender mais sobre isso, eu analisei o básico nesta resposta e nesta resposta , mas não vou culpá-lo se não estiver. ;)
Martin Ender

5
Sim ... o modelo de memória parece um pouco dolorosa (mas ainda melhor do que uma fita de 1D, eu acho)
John Dvorak

144

Motorola MC14500B Código da máquina, 2 bytes

Em hexadecimal:

58EC

Explicação:

5  OR the register with input from the data bus
8  Write the register to the data bus
E  Skip next instruction if register is zero
C  Jump

O Motorola MC14500B é um microcontrolador de 1 bit; possui um registro de 1 bit e um barramento de dados de 1 bit. Como os opcodes são de 4 bits cada, existem apenas dezesseis; metade deles realiza uma operação lógica entre o registrador e o bit no barramento de dados.

A instrução de salto define uma bandeira de salto; quando nenhum endereço é fornecido, é comum definir o contador do programa como 0. Se o bit de entrada for zero, o processador não irá pular. Se o bit de entrada for 1, o processador retornará ao início; como estamos ORcom entrada, não importa qual seja o sinal de entrada depois - o registro será 1 para sempre.

Como é convencional, o registro é inicializado em 0.

Uma lista dos códigos de operação pode ser encontrada na folha de dados ou aqui .


7
2 bytes é definitivamente o mínimo para esse desafio.
Conor O'Brien

23
@ CᴏɴᴏʀO'Bʀɪᴇɴ Estou procurando há várias horas em esolangs e listas de processadores de 4 bits para ver se há 1 ou 1,5 e não encontrei nenhum.
lirtosiast

Definitivamente, a ferramenta certa para o trabalho.
237 Hugo Zink

O link é borked atm ...
TheDoctor

@TheDoctor Ambos os links funcionam bem para mim
Mego

85

Arnold C, 296 bytes

IT'S SHOWTIME
    HEY CHRISTMAS TREE i    
    YOU SET US UP @NO PROBLEMO
    BECAUSE I'M GOING TO SAY PLEASE i
        STICK AROUND i
            TALK TO THE HAND i
        CHILL
    BULLSHIT
        TALK TO THE HAND i
    YOU HAVE NO RESPECT FOR LOGIC
YOU HAVE BEEN TERMINATED

Não é realmente competitivo, mas pela diversão. Não suporta stdin, substitua@NO PROBLEMO com @I LIEDum valor zero. @No Problemoé 1.

Execute com (assumindo que o arquivo seja truthmachine.arnoldc):

wget http://lhartikk.github.io/ArnoldC.jar
java -jar ArnoldC.jar truthmachine.arnoldc
java truthmachine

46
Bela. Eu chorei 10/10
um spaghetto

10
BECAUSE I'M GOING TO SAY PLEASELOL
Eric Martinez

8
Parece que isso if(i){while(i) print(i);} else {print(i);}certamente seria mais curto de fazer print(i);while(i) print(i);?
lirtosiast

16
Embora BULLSHITtenha uma grande contribuição para o valor de entretenimento do programa, tecnicamente é desnecessário. Você pode fatorar todo o BULLSHITramo movendo-o TALK TO THE HAND idepois YOU HAVE NO RESPECT FOR LOGIC.
Gaborsch #

4
@GaborSch Há apenas uma resposta adequada para que: BULLSHIT;)
caird coinheringaahing

65

Minecraft, 18 bytes (versão MC 15w45a)

esboço de minecraft

Como você pode ver, existe uma alavanca direcionada para o bloco de comando repetido, que possui o comando say 1 . Além disso, existe um sinal de tocha invertida, que direciona a energia para o bloco de comando de execução única com o comando say 0nele.

Sempre que o comutador é direcionado para a verdade, o bloco repetidor usa o código say 1para gerar 1s infinitos . Quando a alavanca é redirecionada para false, gera uma única0 .

Observe que isso gera a [@]por padrão. Se você realmente deseja apenas 1s e zeros, isso se torna 34 bytes, onde o código nos blocos de comando é tellraw @a [1]e tellraw @a [0]. Isso está usando a contagem de bytes sugerida por @Cᴏɴᴏʀ O'Bʀɪᴇɴ para o MC, como pode ser encontrado no Meta .


28
Você usou um videogame para o código de golfe. +1
RK.

11
@RK. Esta é realmente uma prática bastante padrão para desafios simples. Existem pelo menos dois outros usuários que usam o MC como idioma de código de golfe - tente a barra de pesquisa com is:answer Minecraft. c:
Addison Crump

11
@FlagAsSpam lol muito bem feito. Além disso, obrigado por essa dica de pesquisar as respostas do MC.
Ashwin Gupta

56

Utilitários Bash + GNU, 13

grep 0||yes 1

Bash, 35

read n;for((;n;));{ echo 1;};echo 0

3
Você sabe, eu estava me perguntando se uma solução festa com sim seria possível ...
um Spaghetto

2
Agradável! Isso é muito inteligente
um Spaghetto

38

Ruby, 20

print while/1/||gets

Execute a partir da linha de comando para evitar avisos, como

ruby -e "print while/1/||gets" <<< 0
ruby -e "print while/1/||gets" <<< 1

Explicação:

Menos golfe, este é

while /1/ || gets
  print
end

Quando um Regexp é usado em uma condição, ele é avaliado como falsey, a menos que a variável $_seja preenchida e corresponda ao padrão. Na primeira vez em que o loop $_está vazio, caímos em gets, que define o valor de $_para uma linha lida em STDIN. printsem argumentos impressos $_. Agora avaliamos o condicional novamente. Se lemos em 1, fazemos um curto-circuito e apenas imprimimos 1 novamente, e assim sucessivamente. Caso contrário, passamos a gets, mas como não há segunda linha de entrada, getsretorna nulo, então o loop termina.


18
É bom quando tarefas triviais ainda permitem soluções surpreendentes, mesmo em idiomas "normais". :)
Martin Ender

A ||getsparte é legal e tudo, mas você não pode simplesmente fazer gets;print while/1/e salvar um byte?
Daniero 27/08/16

Não, então ele não imprime o zero.
histocrat

37

Microscript, 3 bytes

i{p

O mais baixo que eu conheço.

Explicação:

i  Takes numeric input and puts it in register 1
{  while register 1 is truthy
  p  Print the contents of register 1

O microscript tem impressão implícita do registro 1 após o término, razão pela qual uma entrada de 0é impressa uma vez.


@quartata Eu combinei com você: D
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ: O
a spaghetto

2
Eu estou seriamente pensando se você escreveu a questão primeira, ou a resposta ...
John Dvorak

11
A questão. Eu só queria postar isso, já que foi o mais curto que eu encontrei enquanto escrevia a pergunta. É um catálogo, portanto não existem vencedores reais.
a spaghetto

36

Código da máquina de Turing, 32 bytes

Usando a sintaxe da tabela de regras encontrada aqui.

0 0 0 * halt
0 1 1 r 1
1 _ 1 r 1

Eu realmente gosto disso. +1
a spaghetto

Eu sabia que alguém já teria postado isso!
YoYoYonnY

25

JavaScript, 28 bytes

Os loops pois são frequentemente mais curtos do que os loops while.

alert(x)retorna undefined, que é falso, de modo que o bit a bit ou operador |, o lança 0. Assim, se xestiver "0", alerta uma vez, caso contrário, continue em loop. Usa alertpara STDOUT como esta resposta .

for(x=prompt();alert(x)|x;);

Atire, você me venceu. Eu estava prestes a postar exatamente isso! :) GG
Domino

Uau, isso é um pouco mais inteligente que o meu :) Tenha +1!
ETHproductions

Você não precisa do ponto e vírgula à direita.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Qual navegador você usou? Eu testei no Firefox e Chrome e fico SyntaxErrorsem ele.
Intrepidcoder #:

@intrepidcoder Oh, desculpe, meu mal. Minha mente estava no modo "ponto e vírgula à direita é inútil". ^^ "
Conor O'Brien

24

Python 2, 29 bytes

a=input()
while 1:print a;1/a

Isso termina com um erro de divisão ativado 0, o que é permitido por padrão .


A saída STDERR está boa. A resposta> <> a usa também.
a spaghetto

Isso é brilhante ^ _ ^
ABcDexter 01/09/16

Enquanto uma impressão seria um trabalho? Desculpe, eu não sei python.
Rohan Jhunjhunwala

11
@RohanJhunjhunwala Para 0, ele não imprimiria nada, mas deveria imprimi-lo uma vez.
xnor

11
@ xnor oh, meu mal.
Rohan Jhunjhunwala

20

Brainfuck, 41 36 31 30 bytes

Encurtado imprimindo uma vez logo após a entrada e com a ajuda de Ethan e user46915.

,.+++[->>+<-----<]>>---<-[>.<]

Versão anterior: subtraia 48 da entrada e, se não for zero, adicione 1 ao 48 para imprimir ASCII 1para sempre, caso contrário, imprima 0.

-[>+<-----]>--->,<[->->+<<]>[>+<]>.<[>.<]

Eu executei aqui , mas devido à saída em buffer, você não pode ver nenhuma saída, pois o programa nunca termina 1.

Edit: Eu tinha esquecido de imprimir 0na entrada 0. Corrigido agora. Eu gosto dos >.<rostos no final.


11
@ThomasKwa Acho que não, mas não tenho certeza, pois não vejo um algoritmo específico para o módulo 2. O algoritmo divmod é um pouco longo.
mbomb007

2
Você pode reduzi-lo um pouco mais, mesclando os trechos de código um pouco melhor e diretamente usando seu registro de entrada em vez de ter um registro "48" separado:,.[>+>+<<-]-[>-<-----]>+++[>.<]
Ethan

Tentativa de uma solução com o mod 2. Definitivamente, parece que subtrair 48 é o caminho certo a seguir. ,.[->+>+<<]>>[->[>-<[-]]>+[<+>-]<<]>[<<.>>]
cardboard_box

11
@ Ray Esse é o padrão e geralmente é assumido. Se eu tivesse usado outra implementação, eu teria dito isso.
mbomb007

11
Você pode obter mais um byte, combinando subtração e copiando:,.+++[->>+<-----<]>>---<-[>.<]
user46915

19

Piet, 27 18 16 codéis

(Codel é um nome sofisticado para pixel usado para evitar confusão quando uma imagem é esticada para visualização. Contei codels em vez de bytes porque scripts piet são salvos como imagens, para que o tamanho físico possa variar. Acho que um formato de arquivo ideal essa pena o mais eficientemente possível levaria 11 bytes. Na prática, meu pequeno arquivo gif tem 62 bytes, com dados ideais da paleta. Diga-me se devo usar isso como o tamanho da minha entrada, em vez da quantidade de codel.)

Imagem original: versão minúscula

Ampliado: versão ampliada

Em piet, a diferença entre duas cores é o que determina qual comando é executado; portanto, ver a mesma cor duas vezes não significa que ele executa a mesma ação. A execução começa no codel superior esquerdo. Em seguida, ele se move horizontalmente, executando o seguinte:

  1. Leia um número e coloque-o na pilha
  2. Duplique a parte superior da pilha
  3. Estale e produza a parte superior da pilha
  4. Coloque a parte superior da pilha e gire no sentido horário esse número de vezes.

Se a entrada for 1, o cursor se move para baixo no codel lime, que empurra 1 na pilha. Então a execução continua indo para a esquerda. Quando o cursor passa de uma cor para branco e de branco para uma cor, nada acontece. Como o preto também é considerado parede, o cursor acaba voltando para o codel de limão na linha superior e repete tudo da etapa 2.

Se, no entanto, a entrada for 0, o cursor nunca descerá e terminará no J azul à direita (trocadilho intencional, valeu a pena), onde permanecerá preso (porque as partes superior, direita, esquerda e esquerda) os lados inferiores deste bloco em forma de J estão próximos aos codelos pretos ou na borda da imagem). Como o cursor está interceptado, a execução termina.

Valores inesperados:
se o usuário escrever outro número, ele ainda será impresso, o cursor irá girar mais ou menos vezes com base no valor.

  • Múltiplo de 4 ou 0: a execução continua horizontalmente e termina.
  • Múltiplo de 3: Como a subida é impossível, o cursor gira imediatamente no sentido horário e continua na horizontal e depois termina.
  • Múltiplo de 2 e não múltiplo de 4: o cursor gira e começa a se mover para a esquerda. Felizmente, tudo isso faz é executar várias operações que não afetam o fluxo do programa e acabam esvaziando a pilha. Quando uma operação não pode ser realizada porque a pilha está vazia, ela é simplesmente ignorada. Quando atinge o canto superior esquerdo, o cursor não tem mais para onde ir, exceto para a direita novamente, reiniciando efetivamente o programa.
  • Outros valores: o cursor desce como se fosse com 1, o que o faz imprimir 1 para sempre. Se a entrada for 5, a saída será5111111111111...

Qualquer valor não inteiro encerrará o programa. A execução continuará normalmente, mas todas as operações serão ignoradas, pois não há nada na pilha. De certa forma, o programa nunca falha - ele pára normalmente ou faz um loop para sempre.


Versão amigável do PietDev

O PietDev (um Piet IDE online muito básico) parece ter problemas com os codels brancos, por isso criei uma nova versão que gira manualmente de volta em vez de depender da rotação automática adequada do codel branco. E eu nem precisava usar uma nova cor! Se você quiser testar com ele, desenhe uma borda preta ao redor do código, porque o PietDev não suporta tamanhos de programas personalizados.

versão minúscula

versão ampliada


versões mais antigas

A primeira versão não empurrou 1 de volta na pilha e retornou a uma instrução de duplicação anterior. Também possuía codéis inúteis decorativos.

Padrão minúsculo que é realmente um código piet

Versão ampliada

Então tive a ideia de pressionar 1 na pilha para remover a linha em branco. É engraçado como pensei nisso graças aos meus codels decorativos.

versão minúscula

versão grande

Então percebi que tinha um dup estranho que não era mais necessário e reduzi o número de cores para economizar dados da paleta na imagem. Também me livrei do único codel decorativo porque não sei.


7
Eu nunca vi uma resposta Piet marcou em outra coisa senão codels, mas acho que a contagem de bytes ideal também é interessante incluir :)
undergroundmonorail

11
Existem 20 valores de codel diferentes, o que significa que você deve ser capaz de empacotar três codels em 13 bits e oito trigêmeos em 13 bytes para obter uma densidade de armazenamento de 2,6 codels por byte. Mas alguém tem que definir esse idioma primeiro. Sugiro o nome DPPi = piet densamente compactado.
John Dvorak

11
@JanDvorak Contei 21 valores para adicionar um valor especial para quebra de linha, e uma vez que você tenha a primeira quebra de linha, o analisador pode adivinhar onde os outros devem estar. Mas não cheguei a combinar codels em trigêmeos, o que faz muito mais sentido do que desperdiçar 5 bits por codel. Esperto.
Domino

11
Basta adicionar as dimensões como o primeiro par de bytes. Você não precisa de um símbolo extra.
John Dvorak

11
@ quem quiser experimentar: não tente esta solução com o PietDev, porque o PietDev apenas imprime um único 1 e termina. Mas a solução funciona corretamente com o npiet.
ML

19

Pyth, 4 3 2

Wp

um não! espaço à direita (obrigado isaac :)). O espaço costumava ser necessário para compilar o loop while, mas o Pyth foi atualizado. Normalmente isso desqualificaria o uso, mas como esse é um catálogo, ele deve ser válido.

Explicação:

Wp        : implicit Q = eval(input)
W         : while
 p        : print and return the value of Q, to be evaluated as the while condition
          : Functions without enough arguments automatically use Q now
          : do nothing in the body of the while loop

5
Fui inspecionado por esta resposta para adicionar implícito passa Pyth. O espaço agora é desnecessário. pyth.herokuapp.com/?code=WpQ&input=0&debug=0
isaacg 4/15/15

52
Quatro cruzados ainda parecem quatro.
Conor O'Brien

11
Eh, eu só estou ficando tão cansado de seing pyth dominar tudo o tempo todo :( LOL..
Ashwin Gupta

11
@AshwinGupta minha língua tecnicamente vencê-lo, por isso não é completamente dominante :)
Cyoce

@Cyoce yeah! Bom trabalho! Eu tenho certeza de que algo pode bater pyth lol.
Ashwin Gupta

16

Chip , 6 bytes

e*faAs

Chip é uma linguagem 2D que se comporta um pouco como um circuito integrado. Ele recebe entrada, um byte de cada vez, e divide os bits em elementos de entrada individuais. A saída une os valores dos elementos de saída novamente em bytes.

Vamos dividir isso:

*é um sinal de fonte, ele enviará um valor verdadeiro para todos os elementos adjacentes. ee fcorrespondem ao quinto e sexto bit da saída. Então, e*fproduz binário 00110000, que é ASCII char "0".

Agora, A é o primeiro bit de entrada e ao primeiro bit de saída, então aAcopia esse bit de entrada para saída. Portanto, quando combinada com e*f, uma entrada de ASCII "0" produz "0" e "1" produz "1". (Não há interação entre fe a, uma vez que nenhum deles produz nenhum sinal.)

A sextremidade, quando ativada por um sinal verdadeiro, impedirá que a entrada avance para o próximo byte, o que significa que tudo funcionará novamente com a mesma entrada.

Como o primeiro byte de "0" é zero, ele não ativará esse elemento e o programa imprimirá "0" e, assim, esgotará sua entrada, o que lhe permitirá terminar. "1", no entanto, ativa esse elemento, o que significa que "1" é emitido, mas não consumido na entrada, permitindo que o ciclo se repita indefinidamente.

Se os valores 0x0 e 0x1 forem usados ​​para saída, em vez de ASCII, podemos eliminar a e*fparte, resultando em apenas 3 bytes :

aAs

Se o zero precisar terminar sozinho, em vez de esperar que o stdin feche, obtemos o seguinte, que inverte o primeiro byte ~e passa o resultado para t, que finaliza o programa ( 10 bytes ):

aA~te*f
 s

( ttambém não produz sinal, portanto não há interação entre te e.)


2
Boa resposta! Como esse é um desafio do catálogo, não há necessidade de marcar isso como não competitivo, por isso removi esse pedaço para você. Bem-vindo ao PPCG!
Mego

4
Tomei a liberdade de adicionar Chip ao TIO. Experimente online!
Dennis

@ Dennis, pergunta para você: como eu faria o TIO atualizar sua fonte? Na semana passada, corrigi um bug no interpretador de chips, mas ele não propagou a alteração no TIO. É algo que preciso pedir a alguém para fazer por mim?
Phlarx

Eu puxei Chip. Se você precisar de algo atualizado, deixe uma mensagem em talk.tryitonline.net .
Dennis

14

Brainbool , 5 bytes

,.[.]

Brainbool é Brainfuck, mas só opera em pedaços, e faz I / O por meio de 0e 1personagens.


3
Eu sabia que tinha que haver um derivado de BF onde isso pudesse ser feito de maneira viável.
a spaghetto

14
Eu sinto que "Boolfuck" pode ser um nome melhor para ele, mas bem feito independentemente.
James Murphy

2
@JamesMurphy parece que já existe: esolangs.org/wiki/Boolfuck
DLeh

13

LOLCODE, 119 bytes

GIMMEH n
n R SUM OF n AN 0
BOTH SAEM n AN 0, O RLY?
YA RLY
 VISIBLE 0
NO WAI
 IM IN UR l
  VISIBLE 1
 IM OUTTA UR l
OIC

Ungolfed:

HAI

BTW, Read n as a string from STDIN and convert to an integer
GIMMEH n
n R SUM OF n AN 0

BTW, Test n for equality with 0
BOTH SAEM n AN 0, O RLY?
YA RLY
    BTW, Write 0 to STDOUT and exit
    VISIBLE 0
NO WAI
    BTW, Loop forever, printing 1
    IM IN YR l
        VISIBLE 1
    IM OUTTA YR l
OIC

KTHXBYE

1. Qual intérprete você está usando? 2. Você pode MAEK n A NUMBRlançar? 3. Você pode usar em DIFFRINTvez de BOTH SAEMe mudar os condicionais?
lirtosiast

@ThomasKwa Eu estava usando LOLCOFFEE, aquele em repl.it. (Que parece ser baixo no momento, então eu vou testar suas sugestões, uma vez que está de volta.)
Alex A.

Não O RLY?transmite para booleano?
Leaky Nun

@LeakyNun No ...? O RLY?é como um postfix if.
22416 Alex A.

12

C, 37 bytes

Uma visão diferente de como fazê-lo em C.

main(c){for(gets(&c);putchar(c)&1;);}

co padrão é um intvalor 1. gets(&c)obtém uma cadeia de caracteres stdin, aqui subornando o valor de c, hackishly, já que cnão é a char*. putchar(c)imprime o valor de cpara stdoute retorna c. Como '0'48 e '1'49 em ASCII, podemos usar o último bit ( &1) para determinar qual é. Se for '0', o loop é interrompido. Caso contrário, isso dura para sempre.

Compila (com um aviso sobre gets) e roda gcc-4.8em Linux.


2
Presumivelmente, isso só funciona em arquiteturas little-endian.
Neil

@ Neil eu diria que sim.
Cbojar

@ Neil Endianness afeta apenas a ordem de bytes em valores multibyte.
precisa

11
O cpadrão @ LegionMammal978 para an int, que é um valor multibyte, e em uma arquitetura big-endian, getsdefinirá o byte errado.
Neil

11

Labirinto , 7 bytes

 ?+
@!:

Labyrinth é uma linguagem 2D baseada em pilha, em que o fluxo de controle depende do sinal do elemento superior da pilha, verificado após cada instrução. A execução começa a se mover para a direita a partir da primeira instrução válida na linha superior, que é a seguinte ?.

As instruções relevantes são:

?      Input integer
+      Add top two elements (Labyrinth's stack has infinite 0s on the bottom)
:      Duplicate top element
!      Output as number
@      Terminate program

Se a entrada for 0, o IP lê a entrada com ?, adiciona as duas primeiras da pilha ( 0 + 0 = 0) e, em seguida, duplica :e gera !um 0. Aqui encontramos a única junção no programa e precisamos verificar a parte superior da pilha para determinar onde ir. Como o topo é 0, avançamos e terminamos com @.

Por outro lado, se a entrada for 1, seguimos a mesma instrução de antes (mas produzindo um 1) antes de chegar à junção no !. Agora, o topo da pilha é positivo, fazendo com que vire à direita na ?. No EOF Labyrinth, empurra 0, assim fazemos 0 + 1 = 1na +duplicação :e na saída !. Mais uma vez, temos um 1 no topo da pilha e o loop continua.

Para um bônus, aqui está a solução de 7 bytes da @ MartinBüttner, que opera da mesma forma:

?+!@
1!

Observe que, ao contrário da maioria dos idiomas, 1na verdade sai nda pilha e empurra n*10 + 1, facilitando a construção de grandes números. No entanto, como o topo da pilha está vazio nesse ponto, não é diferente de simplesmente pressionar 1.


10

> <> , 7 bytes

i2%:n:,

Isso usa o fato de que> <> pressiona -1 no EOF, que é 1 mod 2. Ele também usa dividir por 0 para finalização (o que é aparentemente bom, pois o consenso é que a saída STDERR é ignorada).

Apenas para referência, sair de forma limpa sem erros é um byte extra:

i2%:n?!;

10

APL, 6 bytes

→⎕←⍣⍲⎕

Explicação:

     ⎕ Read the input, then
 ⎕←    write it out
   ⍣   repeatedly
    ⍲  until NAND of it with itself becomes true.
→      Branch to zero to avoid printing the result again.

11
O segundo e o último caracteres devem parecer diferentes? Porque eles não fazem por mim.
John Dvorak

@JanDvorak Não, são os mesmos.
Alex A.

11
OK, agora eu estou olhando para ele no celular e tudo, mas as duas setas parece o mesmo para mim :-D
John Dvorak

10

Brian & Chuck , 21 bytes

,}<-{-?<SOH>_{+?
_>+{?<.p

Aqui, <SOH> deve ser substituído pelo caractere de controle correspondente (0x01).

Explicação

A idéia básica é subtrair o código de caractere da entrada (48 ou 49) do pfinal de Chuck, o que fornecerá um ?(que é um comando válido) ou um @que não será operado.

,lê o caractere de entrada na primeira célula de Chuck (marcada com _). Queremos diminuir esse valor 0em um loop, enquanto fazemos outras alterações:

}<move-se para pe -diminui-o. Em seguida, {retorna à célula de entrada -que também a diminui. Enquanto isso ainda não for zero, ?dá controle a Chuck. Agora >move a cabeça da fita de Brian uma célula para a direita (que é inicializada 1) e a +incrementa. Em seguida, redefinimos o loop com {?.

Quando a primeira célula de Chuck chegar 0, a <SOH>célula será incrementada para o caractere que lemos de STDIN e pserá ?para entrada 1ou @para entrada0 .

Agora ?não muda mais o controle. O 0ou 1depois é um no-op, como é o byte nulo (representado por _). {volta para a primeira célula de Chuck e +aumenta para garantir que seja positivo, de modo que as ?mãos controlem Chuck.

Esse tempo >+incrementa a célula após o final da fita inicial de Brian. Essa célula é lixo, mas nunca a usaremos. Agora {não digitaliza todo o caminho para a frente da fita de Brian, mas apenas para o _. Portanto, ?é um no-op porque a célula atual é zero. Em seguida, <.move um para a esquerda (a cópia do caractere de entrada) e o imprime.

Finalmente, encontramos o ?or @. Se a entrada foi 0e esta célula é @um no-op e o programa termina. Mas se a entrada foi 1e esta célula é ?entregue a Brian, que {+?redefinirá o loop em Chuck, e agora estamos imprimindo 1s para sempre (até que o número inteiro na célula no final da fita de Brian não caiba na memória mais, suponho ...).

Bônus

O Sp3000 e eu jogamos golfe por vários dias. Começamos em torno de 40 bytes e chegamos a duas soluções completamente diferentes, mas vinculadas, a 26 bytes. Somente quando comecei a escrever a explicação para a minha, a solução de 21 bytes acima me ocorreu. Muito obrigado a Sp por lançar idéias e ensinar uns aos outros alguns truques de golfe na B&C. :)

Esta é sua solução de 26 bytes:

>,----{?{>1?0
#I<?_}<.<<<?

E isso é meu:

,{>-<-?_0+?_1{<?
_®{?_{>.?

Onde ®está um byte com o valor 174 (por exemplo, salve o arquivo como ISO 8859-1).

No núcleo, a mina funciona de maneira semelhante à solução de 21 bytes, na qual ®se }aplica à entrada 1e ~(no-op) para entrada 0, mas a execução é muito menos elegante.

Sua solução é bastante clara: o código-fonte é somente ASCII e não requer um loop para processar a entrada. Em vez disso, ----se transforma 1em -e 0em ,(um não-op para Chuck). Isso -mudará o primeiro ?da fita de Brian para a >, criando assim um fluxo de controle diferente para a 1caixa.


10

Tag cíclico bit a bit , 3 bits ou <1 byte

O Bitwise Cyclic Tag é um dos idiomas mais completos de Turing disponíveis no mercado. Ele funciona com duas cadeias de bits, o programa e os dados . Os bits do programa são lidos ciclicamente e interpretados da seguinte maneira:

  • 0: Exclua o primeiro bit de dados (e o produza em implementações que possuem saída).
  • 1x: Se o primeiro bit de dados for 1, anexe x(representando um 0ou 1) ao final dos dados. (Se o primeiro bit de dados for 0, não faça nada.)

O programa é executado até que a sequência de dados esteja vazia.

Máquina da verdade

110

Quando a sequência de dados está configurada para 0:

  • 11não anexa nada porque o primeiro bit de dados não é 1.
  • 0exclusões / saídas 0.
  • A sequência de dados agora está vazia e o programa é interrompido.

Quando a sequência de dados está configurada para 1:

  • 11acrescenta a 1.
  • 0exclusões / saídas 1.
  • A sequência de dados está de volta a uma única 1e o programa está de volta ao ponto em que foi iniciado, então fazemos um loop para sempre.

9

GNU sed, 10

:;/1/{p;b}

Explicação

  • : definir um rótulo sem nome
  • /1/Se a entrada corresponder ao regex 1, então
  • p imprimir o espaço do padrão (ou seja, 1)
  • b e volte para o rótulo sem nome (para sempre)
  • Se a entrada não foi 1 (ou seja, 0), o espaço do padrão é impresso sem modificação e o programa termina.

Raspe 1 caractere usando :;p;/1/be o sinalizador n , para um total de 9 bytes. Como sed -fé usado de qualquer maneira para executar o arquivo de script, adicionar esse sinalizador extra não requer 2 bytes.
precisa saber é o seguinte

9

Sério , 4 3 bytes

Riscado 4 ainda é 4 :(

,W■

, lê um valor de STDIN. Winicia um loop que é executado enquanto o valor no topo da pilha é verdadeiro, com o corpo . imprime o elemento da pilha superior sem aparecer. O loop é implicitamente fechado no EOF.

Na entrada de 0, o loop nunca é executado (já que 0é falsey), e o programa termina no EOF, automaticamente exibindo e imprimindo todos os valores na pilha. Na entrada de 1(ou qualquer valor que não seja0 , ""ou []), o circuito funciona infinitamente.

Na verdade , a liderança ,não é necessária (graças à entrada implícita), diminuindo a pontuação para 2 bytes.


8

Ter, 34 bytes

1::=12
2::=~1
0::=~0
@::=:::
::=
@

Explicação:

1::=12 Instâncias da substring "1" podem se tornar "12"

2::=~1 Instâncias da substring "2" podem ser removidas, imprimindo "1"

0::=~0 Instâncias da substring "0" podem ser removidas, imprimindo "0"

@::=::: Instâncias da substring "@" podem ser substituídas por seqüências de caracteres da entrada

::= Lista final de regras de substituição

@ A cadeia inicial é "@"


8

Arnold C, 134 bytes

IT'S SHOWTIME
HEY CHRISTMAS TREE i
YOU SET US UP 0         //or 1
STICK AROUND i
TALK TO THE HAND 1
CHILL
TALK TO THE HAND 0
YOU HAVE BEEN TERMINATED

Embora isso não seja tão divertido quanto a outra resposta do ArnoldC , é um jogo de golfe. Por exemplo, o recuo é desnecessário, assim como as macros @NO PROBLEMOe @I LIED.

Testado com esta versão do idioma , que não pode receber entrada.


8

Cubix , 5 6 bytes

Cubix é a nova linguagem bidimensional do @ETHproductions, na qual os comandos são agrupados em torno das faces de um cubo. Intérprete online Agradecemos a @ETHproductions pela economia.

!I\@O

Isso acaba se expandindo para o cubo

  !
I \ @ O
  .

Isso começa com o Icomando Insira um número inteiro na pilha.
\, redireciona o ponteiro da instrução para baixo sobre o no op.
O, gera o valor numérico da parte superior da pilha.
!, pule o próximo comando ( @) se o topo da pilha for verdadeiro. Isso pulará o \redirecionamento se 1
\, redireciona o ponteiro de instruções para o @programa de saída.

Isso tira vantagem do fato de a pilha não ser exibida pelos O ? !comandos.


Agradável. Estou muito feliz em ver alguém usando meu idioma :) Eu tenho outra solução de 6 bytes que usa apenas 5 instruções (mais uma no-op), então talvez eu a publique.
ETHproductions

A @ETHproductions publica com certeza. Eu acho que você tem uma linguagem promissora aqui :)
MickyT

Você pode salvar um byte removendo o ?e apenas usando !:!I\@O
ETHproductions

@ETHproductions muito agradável
MickyT

11
Eu escrevi um brute-forcer para este (aviso: congela seu navegador para um ou dois minutos), que vem com exatamente cinco soluções de 5 bytes: @IOw!, @I?Ov, @!IOw, !IOW@,!I\@O
ETHproductions

7

Foo , 6 bytes

&1($i)

A entrada é codificada como o segundo caractere, pois o Foo não possui entrada STDIN. Não concordamos que Foo seja incrível agora? :)

Explicação

&1          Set current cell to 1
  (  )      Do-while loop (or, at least according to the interpreter)
   $i       Print current cell as int

2
Eu sempre gostei de Foo.
a spaghetto

7

Perl, 18 + 1 = 19 13 + 1 = 14 bytes

print while$_

Execute assim:

echo -n NUM | perl -p truth.pl

Obrigado a ThisSuitIsBlackNot (que é muito melhor no golfe em Perl do que eu) por jogar cinco bytes.


2
Modificadores de declaração são seus amigos! Além disso, se você garantir que a entrada não tenha uma nova linha à direita, poderá soltar +0: echo -n 0 | perl -pe'print while$_'(13 bytes + 1 para -p). perl -M5.010 -pe'say while$_'seria ainda mais curto, mas que resulta em novas linhas inconsistentes entre 0 vs. 1.
ThisSuitIsBlackNot

@ThisSuitIsBlackNot Ah-ha! Tentei imprimir com $ _, mas não consegui descobrir por que não funcionou. Não sabia que você não podia ter a nova linha à direita na entrada.
a spaghetto

Sim, a cadeia 0é falsa, mas 0+ nova linha é verdadeira. Veja perldoc perlsyn.
precisa saber é o seguinte

2
sayé mais curto, mesmo se você contar -Ecomo um byte extra.
Dennis

2
@ Dennis ... que acabei de perceber pode ser corrigido com -l: perl -lpE 'say while$_'(11 bytes + 2 para -lp).
precisa saber é o seguinte

7

> <> , 6 bytes

::n?!;

Empurra a entrada na pilha para iniciar

:        copy top element on stack
 :       copy top element on stack again
  n      pop and outputs top element
   ?     condition trampoline - pops top element, if it is zero skips next instruction
    !    trampoline skips next instruction
     ;   finish execution

11
Aqui no PPCG, adoramos nossas explicações. +1
um spaghetto

3
Eu tenho certeza que isso só funciona com entradas literais 0 e 1, quando deveria funcionar com 48 ( '0') e 49 ( '1'). Estou enganado?
Undergroundmonorail

@quartata Se fosse eu, eu diria que, para ser justo com as respostas que usam dos métodos mais tradicionais de obter informações, você deve colocar 48 ou 49 na pilha. É o seu desafio embora e não é um grande negócio de qualquer maneira assim ¯ \ _ (ツ) _ / ¯
undergroundmonorail

2
Há outro problema com isso: se a pilha estiver preenchida previamente, você precisará adicionar 3 bytes para o -vsinalizador.
El'endia Starman 04/11/2015

11
@ Aaron: Para o que vale a pena, eu também pensei que era de 2 bytes -v, então eu fui corrigido. Então você não é o único. :)
El'endia Starman 4/11
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.