Implementar una máquina de la verdad


148

Una máquina de la verdad (los créditos son para este tipo por haberlo inventado) es un programa muy simple diseñado para demostrar las E / S y controlar el flujo de un lenguaje. Esto es lo que hace una máquina de la verdad:

  • Obtiene un número (0 o 1) de STDIN.

  • Si ese número es 0, imprima 0 y termine.

  • Si ese número es 1, imprima 1 para siempre.

Desafío

Escriba una máquina de la verdad como se describió anteriormente en su idioma de elección. La máquina de la verdad debe ser un programa completo que siga estas reglas:

  • recibir información de STDIN o una alternativa aceptable
    • Si su idioma no puede recibir información de STDIN, puede recibir información de una variable codificada o equivalente adecuado en el programa
  • debe salir a STDOUT o una alternativa aceptable
    • Si su idioma es incapaz de emitir los caracteres 0o 1, el byte o la E / S unaria es aceptable.
  • cuando la entrada es 1, debe imprimir continuamente 1s y solo detenerse si el programa se cierra o se queda sin memoria
  • la salida solo debe ser 0seguida por una o sin nueva línea o espacio, o infinitos 1con cada uno 1seguido de una o sin nueva línea o espacio. No se puede generar otra salida, excepto la salida constante del intérprete de su idioma que no se puede suprimir (como un saludo, códigos de color ANSI o sangría). El uso de nuevas líneas o espacios debe ser coherente: por ejemplo, si elige generar 1una nueva línea después de todo 1, debe tener una nueva línea después de ellos.

  • si y solo si su idioma no puede terminar en una entrada de 0él, es aceptable que el código entre en un bucle infinito en el que no se emite nada.

Como se trata de un catálogo, los idiomas creados después de este desafío pueden competir. Tenga en cuenta que debe haber un intérprete para que se pueda probar el envío. Está permitido (e incluso alentado) escribir este intérprete usted mismo para un lenguaje previamente no implementado. Aparte de eso, se deben obedecer todas las reglas estándar del de . Las presentaciones en la mayoría de los idiomas se puntuarán en bytes en una codificación preexistente apropiada (generalmente UTF-8).

Catalogar

El Fragmento de pila al final de esta publicación genera el catálogo a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

## Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

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

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:

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


¿Podemos suponer que el programa se detiene cuando el procesador termina de ejecutar el código escrito, para una entrada de código de máquina?
lirtosiast el

3
¿Asumiendo que algún comportamiento está bien para todas las entradas inválidas?
Cruncher el

3
@Cruncher Sí, las únicas entradas que debe esperar obtener son 0 y 1.
un espagueti el

44
El catálogo está descorchado.
Addison Crump

2
El catálogo parece tener en cuenta Bfy bfser diferentes idiomas.
Mooing Duck

Respuestas:


189

Hexagonía , 6 bytes.

Esto fue sorprendentemente complicado, y no estoy convencido de que sea óptimo ...

<.@!$?

Después de rellenar y desplegar el código, esto representa la siguiente cuadrícula hexadecimal:

ingrese la descripción de la imagen aquí

Esto utiliza un flujo de control similar al de mi reciente programa de gato libre de errores , que se mueve a lo largo de antiagoniales. Para lograr eso, comenzamos desviando el puntero de instrucción (IP) hacia la izquierda, donde el camino púrpura se envuelve hacia la esquina inferior izquierda.

?lee la entrada como un entero. !lo imprime de nuevo. .es solo un no-op. Ahora la esquina de la cuadrícula actúa como una rama:

Si la entrada fue 0, la IP continuará a lo largo de la ruta roja, que simplemente termina el programa con @.

Si la entrada fue 1, la IP continuará en el camino verde. De nuevo, .es solo un no-op, pero $es el equivalente del trampolín de Befunge: omite la siguiente instrucción. Después del ajuste, la siguiente instrucción sería ?, pero debido a la $ejecución, en realidad continúa en la ruta azul, comenzando con la !impresión de otra copia del archivo 1. Este ciclo que solo contiene !..$ahora se repite indefinidamente.

Un estudio del flujo de control en Hexagony ...

Creo que la solución anterior es óptima. He escrito un forzador bruto, que verifica todos los programas de Hexagonía de 6 bytes, que contienen al menos uno de cada uno ?!@(que son necesarios; También he verificado :y %en lugar de @terminar con un error de división por cero, pero eso tampoco ayudó). La verificación imprime todos los programas que a) producen una 0entrada 0y terminan yb) producen al menos dos 1s (y nada más) y no terminan dentro de los primeros 60 ticks del programa (200 ticks para soluciones de 5 bytes) . Dudo que cualquier solución válida requiera más de 200 ticks para imprimir correctamente la primera 0o la segunda 1en una cuadrícula tan pequeña, así que no creo que me haya perdido ninguna solución potencial.

La búsqueda no arrojó ningún resultado para 5 bytes, pero 57 resultados para 6 bytes (usando @; no hay necesidad de terminar con un error si podemos resolver esto limpiamente en la misma cantidad de bytes). De esos 57, solo 6 eran falsos positivos que en realidad imprimieron solo dos 1sy luego entraron en un bucle infinito sin imprimir más. Una solución se enumeró dos veces porque contenía dos !comandos. Eso deja exactamente 50 soluciones válidas.

Hay una cierta cantidad de degeneración entre las soluciones donde uno o dos caracteres no son sustanciales, por ejemplo, porque de todos modos son efectivamente no operativos. Las soluciones se pueden agrupar en 23 conjuntos de programas genuinamente distintos (en algunos casos, solo hay una única diferencia de caracteres entre dos conjuntos, pero cambia sustancialmente el flujo de control, por lo que los he contado por separado). Dos de los grupos incluso utilizan múltiples punteros de instrucción de una manera muy inesperada. Como nunca habría ideado la mayoría de estas formas de usar las ramas y los espejos, hacen un estudio muy interesante sobre qué tipos de flujo de control son posibles en Hexagony, y definitivamente he aprendido algunos trucos nuevos para futuros campos de golf.

El flujo de control general es casi siempre el mismo: lea un número, imprímalo. Si se trata de 0encontrar una forma de hacerlo @, si no, sigue recorriendo el !tiempo mientras mantienes un valor de borde de 1. Hay cuatro excepciones notables:

  • Una solución (la que tiene dos !) imprime dos 1s por iteración a través de la cuadrícula, por lo tanto, imprime aproximadamente el doble de rápido que la mayoría de los programas. He marcado este con x2abajo.
  • Algunas soluciones (las que contienen un o) reemplazan el 1con a 111(el código de carácter de o), por lo que imprimen tres 1 s por iteración, lo que hace que impriman aproximadamente tres veces más rápido que la mayoría de los programas. Los he marcado con x3abajo.
  • Dos soluciones anexar una 1con el valor de punta en cada iteración (por lo que 1-> 11-> 111-> ...). Esos imprimen muy rápido, pero eventualmente se quedarán sin memoria. Los he marcado con OoMabajo.
  • Dos soluciones entran en un bucle muy cerrado que simplemente rebota hacia adelante y hacia atrás !, imprimiendo en cada tictac (en lugar de cada 5 o más o menos), lo que las hace un poco más rápidas (y más ordenadas). Los he marcado con ><abajo.

Así que aquí está todo el zoológico:

#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

El siguiente es un breve recorrido para un puñado de los grupos más representativos. Especialmente los grupos 10 y 23 valen la pena echarle un vistazo. Hay muchos otros caminos interesantes y a veces complicados en los otros grupos, pero creo que ya te aburrí lo suficiente al final de esto. Para cualquiera que realmente quiera aprender Hexagony, definitivamente vale la pena investigarlos, ya que exhiben aún más usos posibles de los espejos y $.

Grupo 1

Esta no es mucho más elaborada que mi solución original, pero los caminos van en diferentes direcciones. También permite la mayor cantidad de variaciones en una sola celda, ya que el no-op más a la derecha se puede reemplazar con 5 comandos diferentes que aún lo hacen válido sin cambiar la estructura:

ingrese la descripción de la imagen aquí

Grupo 2

Este es bastante interesante, porque solo se mueve horizontalmente. Después de ajustarse al >, la IP se invierte inmediatamente, tomando la rama en la esquina. No es del todo visible el diagrama, pero en el caso de 1que recorramos la primera fila de nuevo, pero esta vez hacia atrás. Esto también significa que nos encontramos ?nuevamente, que ahora regresa 0(EOF). Esto se arregla con )(incremento) para seguir imprimiendo 1s. Esto también tiene 5 variaciones, como )también podría ser 1o o, y >también podría ser |:

ingrese la descripción de la imagen aquí

Grupo 3

Este parece casi idéntico al anterior, pero es desordenado como el infierno. Hasta golpear |y luego atravesar la fila inferior o superior es lo mismo. Pero en el caso de un bucle, el $ahora salta el ) en el espejo. Entonces seguimos el camino turquesa hacia la derecha, ahora tocamos el incremento, saltamos el @antes de pasar al de | nuevo y luego volvemos al camino verde en la parte superior.

ingrese la descripción de la imagen aquí

Grupo 4

Pensé que este era particularmente ingenioso:

ingrese la descripción de la imagen aquí

El _espejo en la esquina superior derecha es inicialmente no operativo, por lo que imprimimos con !y presionamos el botón <. El 0camino ahora golpea el espejo horizontal y termina. Sin 1embargo, el camino toma una trayectoria realmente interesante: se desvía hacia abajo, se envuelve !hacia la horizontal, se redirige hacia la horizontal y luego se envuelve hacia atrás ! nuevamente . Luego sigue moviéndose en esta forma de rombo, imprimiendo dos veces por iteración (cada tercer tic).

Grupo 8

Esta es una de las dos soluciones con un ciclo de impresión realmente ajustado:

ingrese la descripción de la imagen aquí

Los <actos como la rama. Después de envolver dos veces, 0golpes @. 1por otro lado, primero omite el ?, luego lo >envía al de $nuevo, por lo que se omite el @. Luego, la IP se envuelve en el camino turquesa, donde rebota hacia adelante y hacia atrás entre >y <(envolviendo el borde en el medio).

Grupo 10

Uno de los dos grupos que utilizan otros punteros de instrucción, y es absolutamente hermoso. Hexagony tiene 6: cada uno comienza desde una esquina diferente a lo largo del borde en el sentido de las agujas del reloj, pero solo uno de ellos está activo a la vez.

ingrese la descripción de la imagen aquí

Como de costumbre, leemos con ?. Ahora ~es la negación unaria: convierte el 1a -1. A continuación, tocamos el #. Esta es una forma de cambiar entre IP: toma el valor de borde actual módulo 6 y cambia a la IP correspondiente (las IP están numeradas 0en el sentido de las agujas del reloj). Entonces, si la entrada fue 0, entonces la IP simplemente sigue siendo la misma, y ​​viaja aburridamente hacia adelante !@. Pero si la entrada fue 1, entonces el valor actual es -1cuál es 5 (mod 6). Entonces cambiamos a la IP que comienza en la misma celda (la ruta verde). Ahora #es un no-op y ?establece el borde de la memoria en 0. )incrementos para !imprimir a 1. Ahora golpeamos ~nuevamente para asegurarnos de que#sigue siendo un no-op (en lugar de cambiarnos a IP 1 que terminaría el programa). Es sorprendente lo bien que todo encaja en este pequeño programa.

Grupo 22

Solo para tener en cuenta, este es el grupo en el que se encuentra mi solución original. También es el grupo más grande, porque el no-op puede estar en dos lugares diferentes, y hay varias opciones para el comando real (no-op efectivo).

Grupo 23

Este es el otro grupo que usa múltiples IP. De hecho, este utiliza 3 IP diferentes. La esquina superior derecha es un poco desordenada, pero intentaré guiarte a través de esto:

ingrese la descripción de la imagen aquí

Entonces, el comienzo que has visto antes: <desvía el noreste, ?lee la entrada. Ahora ]es otra forma de cambiar entre IP: le da el control a la siguiente IP en el sentido de las agujas del reloj. Así que cambiamos el control al camino turquesa que (sé que es difícil de ver) comienza en la esquina noreste que va hacia el sureste. Se refleja de inmediato en el <modo que se envuelve en la esquina sureste, en dirección noroeste. Es también golpea el ]por lo que cambiar a la siguiente IP. Este es el camino gris que comienza en la esquina este, hacia el suroeste. Imprime la entrada, luego se envuelve a la esquina noreste. <desvía el camino hacia la horizontal, donde es reflejado por el otro < . Ahora la mano derecha<actúa como una rama: si la entrada fue 0, la IP se mueve hacia el noreste y se ajusta al @. Si la entrada fue 1, la IP se mueve hacia el !, se envuelve hacia la izquierda y <donde se refleja ... ahora en la esquina, se devuelve al !, se desvía por la derecha <, se refleja por la izquierda <y comienza el camino terminado...

Todo un desastre, pero un desastre hermoso. :)


Diagramas generados con el sorprendente HexagonyColorer de Timwi .


55
whoa solo whoa
Conor O'Brien el

66
^ de acuerdo. Tan genial ...
El'endia Starman

28
¡Cállate y toma mi voto!
Mego

77
@ThomasOltmann Admito que esta respuesta supone un conocimiento básico del idioma. Si realmente está interesado en aprender más al respecto, he revisado los conceptos básicos en esta respuesta y en esta respuesta , pero no lo culparé si no lo hace. ;)
Martin Ender

55
Sí ... el modelo de memoria parece un poco doloroso (pero aún mejor que una cinta 1D, supongo)
John Dvorak

144

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

En hexadecimal:

58EC

Explicación:

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

El Motorola MC14500B es un microcontrolador de 1 bit; Tiene un registro de 1 bit y un bus de datos de 1 bit. Como los códigos de operación son de 4 bits cada uno, solo hay dieciséis; La mitad de ellos realiza una operación lógica entre el registro y el bit en el bus de datos.

La instrucción de salto establece una bandera de salto; cuando no se proporciona ninguna dirección, es común establecer el contador del programa en 0. Si el bit de entrada era cero, el procesador no saltará. Si el bit de entrada fue 1, el procesador vuelve al inicio; dado que estamos ORcon entrada, no importa cuál sea la señal de entrada después, el registro será 1 para siempre.

Como es convencional, el registro se inicializa a 0.

Puede encontrar una lista de los códigos de operación en la hoja de datos, o aquí .


77
2 bytes es definitivamente el mínimo para este desafío.
Conor O'Brien el

23
@ CᴏɴᴏʀO'Bʀɪᴇɴ He estado buscando durante varias horas a través de esolangs y listas de procesadores de 4 bits para ver si hay un 1 o 1.5, y no he encontrado uno.
lirtosiast el

Definitivamente la herramienta adecuada para el trabajo.
Hugo Zink

Link está descifrado atm ...
TheDoctor

@TheDoctor Ambos enlaces funcionan bien para mí
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

No es realmente competitivo, pero por diversión. No es compatible con stdin, reemplace @NO PROBLEMOcon @I LIEDun valor cero. @No Problemoes 1.

Ejecutar con (suponiendo que el archivo es truthmachine.arnoldc):

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

46
Hermosa. Lloré 10/10
un espagueti

10
BECAUSE I'M GOING TO SAY PLEASELOL
Eric Martinez

8
Parece que esto ¿ if(i){while(i) print(i);} else {print(i);}Seguramente sería más corto de hacer print(i);while(i) print(i);?
lirtosiast el

16
Aunque BULLSHITtiene una gran contribución al valor de entretenimiento del programa, técnicamente es innecesario. Puede factorizar toda la BULLSHITrama moviéndose TALK TO THE HAND idespués YOU HAVE NO RESPECT FOR LOGIC.
gaborsch

44
@GaborSch Solo hay una respuesta adecuada a eso BULLSHIT
:;

65

Minecraft, 18 Bytes (MC Versión 15w45a)

bosquejo de minecraft

Como puede ver, hay una palanca dirigida hacia el bloque de comando de repetición, que tiene el comando say 1en él. Además de eso, hay una antorcha de inversión de señal que dirige la energía hacia el bloque de comando de una sola ejecución con el comando say 0en él.

Cada vez que el interruptor se dirige hacia la verdad, el bloque repetidor usa el código say 1para generar 1s infinitos . Cuando la palanca se redirige a falso, emite un solo 0.

Tenga en cuenta que esto genera un [@]valor predeterminado. Si realmente quiere solo 1s y ceros, esto se convierte en 34 bytes, donde están el código en los bloques de comandos tellraw @a [1]y tellraw @a [0]. Esto está utilizando el recuento de bytes sugerido de @ Cᴏɴᴏʀ O'Bʀɪᴇɴ para MC como se puede encontrar en Meta .


28
Usaste un videojuego para el golf de código. +1
RK.

11
@RK. Esta es en realidad una práctica bastante estándar para desafíos simples. Hay al menos otros dos usuarios que usan MC como lenguaje de golf de código. Pruebe la barra de búsqueda con is:answer Minecraft. c:
Addison Crump

1
@FlagAsSpam lol muy bien hecho. Además, gracias por ese consejo para buscar respuestas de MC.
Ashwin Gupta


38

Rubí, 20

print while/1/||gets

Ejecute desde la línea de comando para evitar advertencias, ya que

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

Explicación:

Menos golf, esto es

while /1/ || gets
  print
end

Cuando se usa un Regexp en un condicional, se evalúa como falsey a menos que la variable $_se complete y coincida con el patrón. La primera vez a través del bucle, $_está vacío, por lo que caemos en gets, lo que establece el valor de $_una línea leída desde STDIN. printsin argumentos impresos $_. Ahora evaluamos el condicional nuevamente. Si leemos en 1, cortocircuitamos y solo imprimimos 1 nuevamente, y así sucesivamente para siempre. De lo contrario, caemos en gets, pero como no hay una segunda línea de entrada, getsdevuelve nil, por lo que el ciclo termina.


18
Es agradable cuando las tareas triviales aún permiten soluciones alucinantes incluso en lenguajes "normales". :)
Martin Ender

La ||getsparte es genial y todo, pero ¿no puedes simplemente hacer gets;print while/1/y guardar un byte?
daniero

No, entonces no imprime el 0 en absoluto.
histocrat

37

Microscript, 3 bytes

i{p

El más corto que conozco.

Explicación:

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

Microscript tiene una impresión implícita del registro 1 al finalizar, que es la razón por la cual una entrada de 0se imprime una vez.


@quartata Te emparejé: D
Conor O'Brien el

@ CᴏɴᴏʀO'Bʀɪᴇɴ: O
un espagueti el

2
Me pregunto seriamente si primero escribiste la pregunta o la respuesta ...
John Dvorak

1
La pregunta. Solo quería publicar esto, ya que fue el más corto que se me ocurrió mientras escribía la pregunta. Es un catálogo, por lo que no hay ganadores reales.
un spaghetto el


25

JavaScript, 28 bytes

Los bucles For suelen ser más cortos que los bucles while.

alert(x)devuelve undefined, que es falso, por lo que el operador u bit a bit |, lo emite 0. Por lo tanto, si xes así "0", alerta una vez, de lo contrario, sigue en bucle. Utiliza alertpara STDOUT como esta respuesta .

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

Dispara, me ganaste. Estaba a punto de publicar exactamente esto! :) GG
Domino

Wow, eso es un poco más inteligente que el mío :) ¡Ten un +1!
ETHproductions

No necesita el punto y coma final.
Conor O'Brien el

@ CᴏɴᴏʀO'Bʀɪᴇɴ ¿Qué navegador usaste? Lo probé en Firefox y Chrome y obtengo un SyntaxErrorsin él.
intrepidcoder

@intrepidcoder Oh, lo siento, mi mal. Mi mente estaba en el modo "los puntos y comas finales son inútiles". ^^ "
Conor O'Brien


20

Brainfuck, 41 36 31 30 bytes

Se acortó imprimiendo una vez justo después de la entrada y con la ayuda de Ethan y user46915.

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

Versión anterior: reste 48 de la entrada, y si no es cero, agregue 1 a 48 para imprimir ASCII 1para siempre, de lo contrario imprima 0.

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

Lo ejecuté aquí , pero debido a la salida almacenada en búfer, no puede ver ninguna salida ya que el programa nunca termina 1.

Editar: se me había olvidado imprimir 0en la entrada 0. Corregido ahora. Me gustan las >.<caras al final.


1
@ThomasKwa Supongo que no, pero no estoy seguro ya que no veo un algoritmo específico para el módulo 2. El algoritmo divmod es un poco largo.
mbomb007

2
Puede acortarlo un poco más fusionando las piezas de código un poco mejor y utilizando directamente su registro de entrada en lugar de tener un registro "48" separado:,.[>+>+<<-]-[>-<-----]>+++[>.<]
Ethan

Intenté una solución con el mod 2. Definitivamente parece que restar 48 es el camino correcto. ,.[->+>+<<]>>[->[>-<[-]]>+[<+>-]<<]>[<<.>>]
caja de cartón

1
@Ray Ese es el valor predeterminado y generalmente se supone. Si hubiera usado otra implementación, lo habría dicho.
mbomb007

1
Puede obtener un byte más combinando resta y copiando juntos:,.+++[->>+<-----<]>>---<-[>.<]
user46915

19

Piet, 27 18 16 codeles

(Codel es un nombre elegante para píxeles que se usa para evitar confusiones cuando una imagen se estira para verla. Conté los codeles en lugar de los bytes porque los scripts piet se guardan como imágenes, por lo que el tamaño físico puede variar. Creo que un formato de archivo ideal guardaría este piet lo más eficientemente posible tomaría 11 bytes. En la práctica, mi pequeño archivo gif es de 62 bytes, con datos de paleta óptimos. Dígame si debo usar esto como el tamaño de mi entrada en lugar de la cantidad de codeles).

Imagen original: versión pequeña

Engrandecido: versión ampliada

En piet, la diferencia entre dos colores es lo que determina qué comando se ejecuta, por lo que ver el mismo color dos veces no significa que realice la misma acción. La ejecución comienza en el códec superior izquierdo. Luego se mueve horizontalmente, realizando lo siguiente:

  1. Lee un número y ponlo en la pila
  2. Duplicar la parte superior de la pila.
  3. Pop y salida de la parte superior de la pila
  4. Haga estallar la parte superior de la pila y gire en sentido horario esa cantidad de veces.

Si la entrada era 1, el cursor se mueve hacia abajo al códel de lima, que empuja 1 en la pila. Luego la ejecución continúa yendo a la izquierda. Cuando el cursor pasa de un color a blanco y de blanco a un color, no pasa nada. Dado que el negro también se considera como paredes, el cursor termina volviendo al codel de cal en la línea superior y repite todo desde el paso 2.

Sin embargo, si la entrada fue 0, el cursor nunca bajará y terminará en la J azul a la derecha (juego de palabras previsto, valió la pena), si permanecerá atrapado (porque la parte superior, derecha, izquierda y los lados inferiores de este bloque en forma de J están al lado de los codeles negros o el borde de la imagen). Como el cursor está atrapado, la ejecución finaliza.

Valores inesperados:
si el usuario escribe otro número, todavía se imprimirá, luego el cursor rotará más o menos veces según el valor.

  • Múltiple de 4 o 0: la ejecución continúa horizontalmente y finaliza.
  • Múltiple de 3: dado que subir es imposible, el cursor gira inmediatamente en sentido horario y continúa horizontalmente, luego termina.
  • Múltiple de 2 y no múltiplo de 4: el cursor gira y comienza a moverse hacia la izquierda. Afortunadamente, todo lo que hace es realizar un montón de operaciones que no afectan el flujo del programa y terminan vaciando la pila. Cuando no se puede realizar una operación porque la pila está vacía, simplemente se ignora. Cuando toca la esquina superior izquierda, el cursor no tiene otro lugar a donde ir sino a la derecha nuevamente, reiniciando efectivamente el programa.
  • Otros valores: el cursor baja como si fuera 1, lo que hace que imprima 1 para siempre. Si la entrada es 5, la salida será5111111111111...

Cualquier valor no entero terminará el programa. La ejecución continuará normalmente, pero todas las operaciones serán ignoradas ya que no hay nada en la pila. Entonces, en cierto modo, el programa nunca se bloquea: se detiene normalmente o se repite para siempre.


Versión amigable de PietDev

PietDev (un IDE de Piet en línea muy básico) parece tener problemas con los códeles blancos, así que hice una nueva versión que gira manualmente hacia atrás en lugar de depender de la rotación automática del codel blanco adecuado. ¡Y ni siquiera necesitaba usar un nuevo color! Si desea probarlo, asegúrese de dibujar un borde negro alrededor del código porque PietDev no admite tamaños de programa personalizados.

versión pequeña

versión ampliada


versiones mas antiguas

La primera versión no hizo retroceder 1 en la pila y en su lugar volvió a una instrucción de duplicación anterior. También tenía codeles decorativos inútiles.

Diminuto patrón que en realidad es un código piet

Versión ampliada

Entonces tuve la idea de presionar 1 en la pila para eliminar la línea en blanco. Es curioso cómo lo pensé gracias a mis codeles decorativos.

versión pequeña

versión grande

Luego me di cuenta de que tenía un duplicado extraño que ya no era necesario, y reduje la cantidad de colores para guardar los datos de la paleta en la imagen. También me deshice del codel decorativo único porque no lo sé.


77
Nunca he visto una respuesta Piet anotó en otra cosa que no sea CODELs, pero creo que la cuenta de bytes óptima también es interesante incluir :)
undergroundmonorail

1
Hay 20 valores de codeles diferentes, lo que significa que debería poder empaquetar tres codeles en 13 bits, luego ocho triples en 13 bytes para una densidad de almacenamiento de 2.6 codeles por byte. Pero alguien tiene que definir ese idioma primero. Sugiero el nombre DPPi = piet densamente empaquetado.
John Dvorak

1
@ JanDvorak Conté 21 valores para agregar uno especial para el salto de línea, y una vez que tienes el primer salto de línea, el analizador puede adivinar dónde deberían estar los otros. Pero no fui tan lejos como la combinación de códeles en trillizos, lo que tiene mucho más sentido que perder 5 bits por cóctel. Inteligente.
Domino

1
Simplemente agregue las dimensiones como el primer par de bytes. No necesitas un símbolo extra.
John Dvorak

1
@todos los que quieran probarlo: no intente esta solución con PietDev porque PietDev solo imprime un 1 y finaliza. Pero la solución funciona correctamente con npiet.
ML

19

Pyth 4 4 3 2

Wp

Hay un no! espacio final (gracias isaac :)). El espacio solía ser necesario para hacer la compilación del bucle while, pero Pyth se ha actualizado desde entonces. Normalmente eso descalificaría su uso, pero como se trata de un catálogo, debería ser válido.

Explicación:

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

55
Esta respuesta me inspiró para agregar implícito passa Pyth. El espacio ahora es innecesario. pyth.herokuapp.com/?code=WpQ&input=0&debug=0
isaacg

52
Cruzó cuatro todavía parece un cuatro.
Conor O'Brien el

1
Eh, me estoy aburriendo tanto de ver a Pyth dominar todo todo el tiempo :(. LOL.
Ashwin Gupta

1
@AshwinGupta mi lenguaje técnicamente lo supera, por lo que no es completamente dominante :)
Cyoce

@Cyoce, sí! ¡Buen trabajo! Estoy seguro de que algo puede vencer a pyth lol.
Ashwin Gupta

16

Chip de 6 bytes

e*faAs

Chip es un lenguaje 2D que se comporta un poco como un circuito integrado. Toma entrada, un byte a la vez, y divide los bits en elementos de entrada individuales. La salida vuelve a unir los valores de los elementos de salida en bytes.

Analicemos esto:

*es una señal fuente, enviará un valor verdadero a todos los elementos adyacentes. ey fcorresponden al quinto y sexto bit de la salida. Entonces, e*fproduce binario 00110000, que es ASCII char "0".

Ahora, Aes el primer bit de entrada y aes el primer bit de salida, por lo aAque copia ese bit de entrada a salida. Entonces, cuando se combina con e*f, una entrada de ASCII "0" produce "0" y "1" produce "1". (No hay interacción entre fy a, ya que ninguno produce ninguna señal).

Al sfinal, cuando se activa mediante una señal verdadera, evitará que la entrada avance al siguiente byte, lo que significa que todo volverá a funcionar con la misma entrada.

Como el primer byte de "0" es cero, no activará este elemento y el programa imprimirá "0" y, por lo tanto, agotará su entrada, lo que le permite terminar. Sin embargo, "1" activa este elemento, lo que significa que se emite "1", pero no se consume en la entrada, lo que permite que el ciclo se repita indefinidamente.

Si los valores 0x0 y 0x1 se utilizan para la salida, en lugar de ASCII, podemos eliminar la e*fparte, lo que resulta en solo 3 bytes :

aAs

Si el cero debe terminar por sí mismo, en lugar de esperar que stdin se cierre, obtenemos lo siguiente, que invierte el primer byte ~y pasa el resultado a t, que termina el programa ( 10 bytes ):

aA~te*f
 s

( ttampoco produce señal, por lo que no hay interacción entre ty e.)


2
¡Buena respuesta! Dado que este es un desafío de catálogo, no hay necesidad de marcarlo como no competitivo, por lo que he eliminado esa parte por usted. Bienvenido a PPCG!
Mego

44
Me tomé la libertad de agregar Chip a TIO. Pruébalo en línea!
Dennis

@Dennis, pregunta para usted: ¿cómo conseguiría que TIO actualice su fuente? La semana pasada arreglé un error en el intérprete de Chip, pero no ha propagado el cambio a TIO. ¿Es esto algo que debo pedirle a alguien que haga por mí?
Phlarx

Tiré de Chip. Si necesita algo actualizado, simplemente deje un mensaje en talk.tryitonline.net .
Dennis


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

Sin golf:

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. ¿Qué intérprete estás usando? 2. ¿Puedes MAEK n A NUMBRlanzar? 3. ¿Se puede usar en DIFFRINTlugar de BOTH SAEMcambiar los condicionales?
lirtosiast el

@ThomasKwa Estaba usando LOLCOFFEE, el de repl.it. (Lo que parece estar inactivo en este momento, por lo que probaré sus sugerencias una vez que vuelva a funcionar.)
Alex A.

¿No se O RLY?convierte en booleano?
Leaky Nun

@LeakyNun No ...? O RLY?Es como un postfix if.
Alex A.

12

C, 37 bytes

Una opinión diferente sobre cómo hacerlo en C.

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

cel valor predeterminado es un intvalor 1. gets(&c)obtiene una cadena de stdin, aquí golpeando el valor de c, hackishly ya cque no es un char*. putchar(c)imprime el valor de cto stdouty devuelve c. Como '0'es 48 y '1'49 en ASCII, podemos usar el último bit ( &1) para determinar cuál es. Si es así '0', el bucle se rompe. De lo contrario, se va para siempre.

Compila (con una advertencia sobre gets) y se ejecuta gcc-4.8en Linux.


2
Presumiblemente esto solo funciona en arquitecturas little-endian.
Neil

@Neil, supongo que sí.
cbojar

@Neil Endianness solo afecta el orden de bytes en valores multibyte.
LegionMammal978

1
@ LegionMammal978 tiene como valor cpredeterminado un intvalor multibyte y, en una arquitectura big endian, getsestablecerá el byte incorrecto.
Neil

11

Laberinto , 7 bytes

 ?+
@!:

Labyrinth es un lenguaje basado en la pila 2D donde el flujo de control depende del signo del elemento superior de la pila, verificado después de cada instrucción. La ejecución comienza a moverse hacia la derecha desde la primera instrucción válida en la fila superior, que aquí está ?.

Las instrucciones relevantes son:

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

Si la entrada es 0, el IP lee la entrada con ?, agrega los dos primeros de la pila ( 0 + 0 = 0), luego duplica :y genera !un 0. Aquí encontramos la única unión en el programa, y ​​tenemos que verificar la parte superior de la pila para determinar dónde ir. Como la parte superior es 0, avanzamos y terminamos con @.

Por otro lado, si la entrada es 1, hacemos la misma instrucción que antes (pero sacando un 1) antes de llegar a la unión en el !. Ahora la parte superior de la pila es positiva, lo que nos hace girar a la derecha hacia el ?. En EOF Labyrinth empuja 0, así que lo hacemos 0 + 1 = 1en +, duplicar :y salida !. Una vez más tenemos un 1 en la parte superior de la pila y el ciclo continúa.

Para obtener una bonificación, aquí está la solución de 7 bytes de @ MartinBüttner, que funciona de manera similar:

?+!@
1!

Tenga en cuenta que, a diferencia de la mayoría de los idiomas, en 1realidad sale nde la pila y empuja n*10 + 1, lo que facilita la creación de grandes números. Sin embargo, dado que la parte superior de la pila está vacía en ese punto, no es diferente de simplemente presionar 1.


10

> <> , 7 bytes

i2%:n:,

Esto usa el hecho de que> <> empuja -1 en EOF, que es 1 mod 2. También usa dividir por 0 para la terminación (lo cual aparentemente está bien ya que el consenso es que la salida STDERR se ignora).

Solo como referencia, salir limpiamente sin errores es un byte adicional:

i2%:n?!;

10

APL, 6 bytes

→⎕←⍣⍲⎕

Explicación:

     ⎕ 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.

1
¿Se supone que el segundo y el último personaje tienen un aspecto diferente? Porque no lo hacen por mí.
John Dvorak

@ JanDvorak No, son lo mismo.
Alex A.

1
Bien, ahora lo estoy mirando en el móvil y todo menos las dos flechas me parecen iguales :-D
John Dvorak

10

Brian y Chuck , 21 bytes

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

Aquí, <SOH>debe reemplazarse con el carácter de control correspondiente (0x01).

Explicación

La idea básica es restar el código de caracteres de la entrada (48 o 49) pal final de Chuck, que dará un ?(que es un comando válido) o @un no operativo.

,lee el carácter de entrada en la primera celda de Chuck (marcada con _). Queremos disminuir este valor 0en un bucle, mientras hacemos otros cambios:

}<se mueve hacia py lo -decrementa. Luego {vuelve a la celda de entrada -que también disminuye. Mientras esto todavía no sea cero, ?le da el control a Chuck. Ahora >mueve el cabezal de cinta de Brian una celda hacia la derecha (que se inicializa 1) e +incrementa eso. Luego reiniciamos el ciclo con {?.

Para cuando llegue la primera celda de Chuck 0, la <SOH>celda se habrá incrementado al carácter que hemos leído de STDIN y pserá ?para entrada 1o @para entrada 0.

Ahora ?ya no cambia el control. El 0o 1después es un no-op, como lo es el byte nulo (representado por _). {regresa a la primera celda de Chuck e +incrementa para asegurarse de que sea positivo, de modo que las ?manos controlen a Chuck.

Este tiempo >+incrementa la celda después del final de la cinta inicial de Brian. Esa celda es basura pero nunca la usaremos. Ahora {no se escanea hasta el frente de la cinta de Brian, sino solo hacia el _. Por ?lo tanto, es un no-op porque la celda actual es cero. Luego <.mueve uno a la izquierda (la copia del carácter de entrada) y lo imprime.

Finalmente, nos encontramos con el ?o @. Si la entrada fue 0y esta celda es @no operativa, el programa finaliza. Pero si la entrada fue 1y esta celda es ?entregada a Brian, quien {+?restablecerá el bucle en Chuck, y ahora estamos imprimiendo 1s para siempre (hasta que el número entero en la celda al final de la cinta de Brian no cabe en la memoria) más, supongo ...).

Prima

Sp3000 y yo hemos estado jugando golf en esto durante varios días. Comenzamos alrededor de 40 bytes y llegamos a dos soluciones completamente diferentes, pero vinculadas a 26 bytes. Solo cuando comencé a escribir la explicación para la mía, se me ocurrió la solución de 21 bytes anterior. Muchas gracias a Sp por lanzar ideas y enseñarnos unos a otros trucos de golf en B&C. :)

Esta es su solución de 26 bytes:

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

Y esto es mío:

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

Donde ®es un byte con valor 174 (por ejemplo, solo guarde el archivo como ISO 8859-1).

En el núcleo, la mina funciona de manera similar a la solución de 21 bytes, ya que se ®convierte }en entrada 1y ~(no-op) para entrada 0, pero la ejecución es mucho menos elegante.

Su solución es bastante clara, ya que el código fuente es solo ASCII y no requiere un bucle para procesar la entrada. En cambio, se ----convierte 1en -y 0en ,(un no-op para Chuck). Eso -cambiará el primero ?de la cinta de Brian en a >, creando así un flujo de control diferente para el 1caso.


10

Etiqueta cíclica bit a bit, 3 bits o <1 byte

Bitwise Cyclic Tag es uno de los lenguajes más completos de Turing. Funciona con dos cadenas de bits, el programa y los datos . Los bits del programa se leen cíclicamente y se interpretan de la siguiente manera:

  • 0: Eliminar el primer bit de datos (y generarlo, en implementaciones que tengan salida).
  • 1x: Si el primer bit de datos es 1, agregue x(representando cualquiera 0o 1) al final de los datos. (Si el primer bit de datos es 0, no haga nada).

El programa se ejecuta hasta que la cadena de datos esté vacía.

Máquina de la verdad

110

Cuando la cadena de datos se establece en 0:

  • 11no agrega nada porque el primer bit de datos no lo es 1.
  • 0elimina / salidas 0.
  • La cadena de datos ahora está vacía y el programa se detiene.

Cuando la cadena de datos se establece en 1:

  • 11anexa a 1.
  • 0elimina / salidas 1.
  • La cadena de datos vuelve a un solo 1y el programa vuelve a donde comenzó, por lo que hacemos un bucle para siempre.

9

GNU sed, 10

:;/1/{p;b}

Explicación

  • : definir una etiqueta sin nombre
  • /1/Si la entrada coincide con la expresión regular 1, entonces
  • p imprimir el espacio del patrón (es decir, 1)
  • b y volver a la etiqueta sin nombre (para siempre)
  • Si la entrada no fue 1 (es decir, 0), el espacio del patrón se imprime sin modificaciones y el programa finaliza.

Elimine 1 carácter usando :;p;/1/by la bandera n , para un total de 9 bytes. Como sed -fse usa de todos modos para ejecutar el archivo de script, agregar ese indicador adicional no requiere 2 bytes.
seshoumara

9

En serio , 4 3 bytes

Tachado 4 sigue siendo 4 :(

,W■

,lee un valor de STDIN. Wcomienza un ciclo que se ejecuta mientras el valor en la parte superior de la pila es verdadero, con el cuerpo . imprime el elemento de la pila superior sin reventar. El ciclo está implícitamente cerrado en EOF.

Al ingresar 0, el ciclo nunca se ejecuta (ya que 0es falsey), y el programa termina en EOF, apareciendo e imprimiendo automáticamente cada valor en la pila. En la entrada de 1(o cualquier valor que no es 0, ""o []), el bucle se ejecuta infinitamente.

En realidad , el inicio ,no es necesario (gracias a la entrada implícita), lo que reduce la puntuación a 2 bytes.


8

Jue, 34 bytes

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

Explicación:

1::=12 Las instancias de la subcadena "1" pueden convertirse en "12"

2::=~1 Las instancias de la subcadena "2" se pueden eliminar, imprimiendo "1"

0::=~0 Las instancias de la subcadena "0" se pueden eliminar, imprimiendo "0"

@::=::: Las instancias de la subcadena "@" se pueden reemplazar con cadenas de la entrada

::= Lista final de reglas de sustitución

@ La cadena inicial es "@"


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

Si bien esto no es tan entretenido como la otra respuesta de ArnoldC , es un juego de golf. Por ejemplo, la sangría es innecesaria, al igual que las macros @NO PROBLEMOy @I LIED.

Probado con esta versión del lenguaje , que no puede recibir información.


8

Cubix , 5 6 bytes

Cubix es el nuevo lenguaje bidimensional de @ETHproductions donde los comandos se envuelven alrededor de las caras de un cubo. Intérprete en línea Gracias a @ETHproductions por el ahorro.

!I\@O

Esto termina expandido al cubo

  !
I \ @ O
  .

Esto comienza con el Icomando. Ingrese un número entero en la pila.
\, redirige el puntero de instrucciones hacia abajo sobre el no op.
O, genera el valor numérico de la parte superior de la pila.
!, omita el siguiente comando ( @) si la parte superior de la pila es verdadera. Esto saltará la \redirección si 1
\, redirige el puntero de instrucción al @programa de salida.

Esto aprovecha el hecho de que los O ? !comandos no revelan la pila .


Agradable. Estoy muy contento de ver a alguien más usando mi idioma :) Tengo otra solución de 6 bytes que solo usa 5 instrucciones (más un no-op), así que quizás publique eso.
ETHproductions

@ETHproductions lo publica con seguridad. Creo que tienes un lenguaje prometedor aquí :)
MickyT

Puede guardar un byte quitando ?y simplemente usando !:!I\@O
ETHproductions

@ETHproductions muy agradable
MickyT

1
He escrito un bruta forzador para esto (advertencia: congela su navegador por un minuto o dos), que viene con exactamente cinco soluciones de 5 bytes: @IOw!, @I?Ov, @!IOw, !IOW@,!I\@O
ETHproductions

7

Foo , 6 bytes

&1($i)

La entrada está codificada como el segundo carácter, ya que Foo no tiene entrada STDIN. ¿No estamos de acuerdo en que Foo es increíble ahora? :)

Explicación

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

2
Siempre me ha gustado Foo.
un espagueti

7

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

print while$_

Corre así:

echo -n NUM | perl -p truth.pl

Gracias a ThisSuitIsBlackNot (que es mucho mejor en Perl golf que yo) por jugar golf de cinco bytes.


2
¡Los modificadores de declaraciones son tus amigos! Además, si se asegura de que la entrada no tiene una nueva línea final, puede descartar +0: echo -n 0 | perl -pe'print while$_'(13 bytes + 1 para -p). perl -M5.010 -pe'say while$_'sería aún más corto, pero que se traduce en nuevas líneas inconsistentes entre 0 vs 1.
ThisSuitIsBlackNot

@ThisSuitIsBlackNot Ah-ha! Intenté imprimir mientras $ _ pero no pude entender por qué no funcionó. No me di cuenta de que no podía tener la nueva línea final en la entrada.
un spaghetto el

Sí, la cadena 0es falsa pero 0+ nueva línea es verdadera. Ver perldoc perlsyn.
ThisSuitIsBlackNot

2
sayes más corto, incluso si cuenta -Ecomo un byte adicional.
Dennis

2
@Dennis ... que acabo de darme cuenta se puede arreglar con -l: perl -lpE 'say while$_'(11 bytes + 2 para -lp).
ThisSuitIsBlackNot

7

> <> , 6 bytes

::n?!;

Empuja la entrada en la pila para comenzar

:        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

1
Aquí en PPCG, amamos nuestras explicaciones. +1
un spaghetto el

3
Estoy bastante seguro de que esto solo funciona con entradas literales 0 y 1, cuando se supone que funciona con 48 ( '0') y 49 ( '1'). ¿Estoy equivocado?
undergroundmonorail

@quartata Si fuera yo, diría que, para ser justos con las respuestas que utilizan métodos más tradicionales para obtener información, debería poner 48 o 49 en la pila. Sin embargo, es su desafío y no es un gran problema, así que ¯ \ _ (ツ) _ / ¯
undergroundmonorail

2
Hay otro problema con esto: si la pila está rellenada previamente, entonces debe agregar 3 bytes para la -vbandera.
El'endia Starman el

1
@ Aaron: Por lo que vale, yo también pensé que eran 2 bytes -v, luego me corrigieron. Entonces no eres el único. :)
El'endia Starman el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.