¡Golf un quine por un gran bien!

204

Usando su idioma de elección, juegue al golf .

Un quine es un programa de computadora no vacío que no toma entrada y produce una copia de su propio código fuente como su única salida.

Sin trampas, eso significa que no puede simplemente leer el archivo fuente e imprimirlo. Además, en muchos idiomas, un archivo vacío también es una quine: eso tampoco se considera una quine legítima.

Sin errores quines: ya existe un desafío por separado para los errores quines.

Puntos por:

  • Código más pequeño (en bytes)
  • La solución más ofuscada / oscura
  • Usar lenguajes esotéricos / oscuros
  • Uso exitoso de idiomas difíciles de jugar en el golf

El siguiente fragmento de pila se puede utilizar para obtener una vista rápida de la puntuación actual en cada idioma, y ​​así saber qué idiomas tienen respuestas existentes y qué tipo de objetivo tiene que vencer:

Rafe Kettler
fuente
44
¿No quiere decir, "Golf un quine para mayor bien"?
Mateen Ulhaq
50
@muntoo es una obra de teatro en "Learn you a Haskell for Great Good".
Rafe Kettler

Respuestas:

106

Hexagonía , longitud lateral 17 16, 816 705 bytes

180963109168843880558244491673953327577233938129339173058720504081484022549811402058271303887670710274969455065557883702369807148960608553223879503892017157337685576056512546932243594316638247597075423507937943819812664454190530214807032600083287129465751195839469777849740055584043374711363571711078781297231590606019313065042667406784753422844".".>.@.#.#.#.#.#.#.#.>.(...........................<.".......".".>./.4.Q.;.+.<.#.>...........................<.".....".".>.#.#.>.N.2.'.\.>.............=.=......._.<.".....".".>.>.;.'.=.:.\.>.......................<."...".".>.\.'.%.'.<.#.>..............._.....<."...".".>.#.#.>.<.#.>...............=.=.<.".".".>.#.\.'.R./.>.................<.".!.........../.>.

Pruébalo en línea!

Esto es lo que parece desplegado:

                1 8 0 9 6 3 1 0 9 1 6 8 8 4 3 8
               8 0 5 5 8 2 4 4 4 9 1 6 7 3 9 5 3
              3 2 7 5 7 7 2 3 3 9 3 8 1 2 9 3 3 9
             1 7 3 0 5 8 7 2 0 5 0 4 0 8 1 4 8 4 0
            2 2 5 4 9 8 1 1 4 0 2 0 5 8 2 7 1 3 0 3
           8 8 7 6 7 0 7 1 0 2 7 4 9 6 9 4 5 5 0 6 5
          5 5 7 8 8 3 7 0 2 3 6 9 8 0 7 1 4 8 9 6 0 6
         0 8 5 5 3 2 2 3 8 7 9 5 0 3 8 9 2 0 1 7 1 5 7
        3 3 7 6 8 5 5 7 6 0 5 6 5 1 2 5 4 6 9 3 2 2 4 3
       5 9 4 3 1 6 6 3 8 2 4 7 5 9 7 0 7 5 4 2 3 5 0 7 9
      3 7 9 4 3 8 1 9 8 1 2 6 6 4 4 5 4 1 9 0 5 3 0 2 1 4
     8 0 7 0 3 2 6 0 0 0 8 3 2 8 7 1 2 9 4 6 5 7 5 1 1 9 5
    8 3 9 4 6 9 7 7 7 8 4 9 7 4 0 0 5 5 5 8 4 0 4 3 3 7 4 7
   1 1 3 6 3 5 7 1 7 1 1 0 7 8 7 8 1 2 9 7 2 3 1 5 9 0 6 0 6
  0 1 9 3 1 3 0 6 5 0 4 2 6 6 7 4 0 6 7 8 4 7 5 3 4 2 2 8 4 4
 " . " . > . @ . # . # . # . # . # . # . # . > . ( . . . . . .
  . . . . . . . . . . . . . . . . . . . . . < . " . . . . . .
   . " . " . > . / . 4 . Q . ; . + . < . # . > . . . . . . .
    . . . . . . . . . . . . . . . . . . . . < . " . . . . .
     " . " . > . # . # . > . N . 2 . ' . \ . > . . . . . .
      . . . . . . . = . = . . . . . . . _ . < . " . . . .
       . " . " . > . > . ; . ' . = . : . \ . > . . . . .
        . . . . . . . . . . . . . . . . . . < . " . . .
         " . " . > . \ . ' . % . ' . < . # . > . . . .
          . . . . . . . . . . . _ . . . . . < . " . .
           . " . " . > . # . # . > . < . # . > . . .
            . . . . . . . . . . . . = . = . < . " .
             " . " . > . # . \ . ' . R . / . > . .
              . . . . . . . . . . . . . . . < . "
               . ! . . . . . . . . . . . / . > .
                . . . . . . . . . . . . . . . .

Ah, bueno, esta fue la montaña rusa emocional ... Dejé de contar la cantidad de veces que cambié entre "jaja, esto es una locura" y "espera, si hago esto debería ser bastante factible". Las restricciones impuestas en el código por las reglas de diseño de Hexagony fueron ... severas.

Es posible reducir la longitud del lado en 1 o 2 sin cambiar el enfoque general, pero será difícil (solo las celdas con #las que no se utilizan actualmente y están disponibles para el decodificador). Por el momento tampoco tengo absolutamente ninguna idea de cómo un enfoque más eficiente, pero estoy seguro de que existe. Pensaré en esto durante los próximos días y tal vez intente jugar golf a un lado, antes de agregar una explicación y todo.

Bueno, al menos, he demostrado que es posible ...

Algunos scripts de CJam para mi propia referencia futura:

Martin Ender
fuente
51
Querido Peter, ¿qué es esto?
Conor O'Brien
2
¿Cuánto tiempo llevó hacer esto?
Adnan
3
@AandN He estado jugando con conceptos para una "plantilla" general desde ayer de vez en cuando (eso no implicaba ninguna prueba real ... simplemente escribía algunas cosas en una cuadrícula de 7x7 y veía si podía funcionar ... Descarté probablemente media docena de enfoques ya allí). La codificación real tomó esta tarde ... quizás 3 horas, diría.
Martin Ender
10
Las palabras no pueden explicar cuán asombrado estoy al ver esto en acción con Esoteric IDE paso a paso ... Para quién quiera entender esto, este Hexágono codifica la parte del "decodificador" en un número entero que se imprime con !y luego con un espejo /en la 2da última línea ingresa al decodificador para imprimir el código del decodificador para completar el quine. Esto tiene un uso milagroso <y >lee el entero multilínea muy grande y construyó el área para almacenar el decodificador. Realmente me encantaría saber qué "docenas de enfoques" se están considerando?
Sunny Pun
3
¿Explicación? ---
MD XF
77

MySQL, 167 caracteres

SELECT REPLACE(@v:='SELECT REPLACE(@v:=\'2\',1+1,REPLACE(REPLACE(@v,\'\\\\\',\'\\\\\\\\\'),\'\\\'\',\'\\\\\\\'\'));',1+1,REPLACE(REPLACE(@v,'\\','\\\\'),'\'','\\\''));

Eso es correcto. :-)

Realmente escribí este yo mismo. Fue publicado originalmente en mi sitio .

TehShrike
fuente
72

GolfScript, 2 bytes

1

(nota nueva línea final) Esto empuja el número 1 en la pila. Al final del programa, GolfScript imprime todos los elementos de la pila (sin espacios en el medio), luego imprime una nueva línea.

Esta es una quine verdadera (como se enumera en la pregunta), porque realmente ejecuta el código; no solo "lee el archivo fuente e lo imprime" (a diferencia del envío de PHP).


Para otro ejemplo, aquí hay un programa GolfScript para imprimir 12345678:

9,(;
  1. 9: empuje 9 a la pila
  2. ,: consume el 9 como argumento, empuja la matriz [0 1 2 3 4 5 6 7 8]a la pila
  3. (: consume la matriz como argumento, empuja la matriz [1 2 3 4 5 6 7 8]y el elemento 0a la pila
  4. ;: descarta el elemento superior de la pila

La pila ahora contiene la matriz [1 2 3 4 5 6 7 8]. Esto se escribe en la salida estándar sin espacios entre los elementos, seguido de una nueva línea.

Chris Jester-Young
fuente
18
O PowerShell, o PHP :-)
Joey
66
No retrocediste en el tiempo y le diste al inventor la idea de inventar GolfScript, ¿verdad?
Mateen Ulhaq
78
Técnicamente, 1no es una quine en GolfScript: genera 1\n, donde \ndenota una nueva línea. Sin embargo, el programa de dos char 1\n es una quine.
Ilmari Karonen
17
El programa one-char \nprobablemente también lo es?
Lynn el
10
@ Seudónimo a quine es literalmente un programa que imprime su propia fuente. No creo que haya restricciones arbitrarias sobre la "estructura".
Hugo Zink
71

Cerebro-Flak , 9.8e580 1.3e562 9.3e516 12818 11024 4452 4332 4240 4200 4180 3852 3656 3616 3540 2485 + 3 = 2488 bytes

¡Ahora cabe en el universo observable!

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()())([[]]){({}()<(([{}]())<{({}())<>(((((()()()()()){}){}){}())[()])<>{({}())<>{}({}(((()()()){}())){}{})<>{({}())<>({}(((()()()()()){})){}{}())<>{{}<>({}(((()()()()){}){}){})(<>)}}<>(({})[()()])<>}}{}<>({}(<()>)<><{({}<>)<>}<>>){({}<>)<>}{}(<>)<>{({}<>)<>}{}(((((((()()()()()){}){}){}))()))>){({}()<((({}[()])()))>)}{}<>{({}<>)<>}{}>)}{}<>{({}<>)<>}<>

Pruébalo en línea!


Explicación

Este Quine funciona como la mayoría de los Quines en lenguajes esotéricos; Tiene dos partes, un codificador y un decodificador. El codificador es todos los paréntesis al principio y el decodificador es la parte más compleja al final.

Una forma ingenua de codificar el programa sería colocar el valor ASCII de cada carácter en el decodificador en la pila. Esta no es una muy buena idea porque Brain-Flak solo usa 8 caracteres ( ()<>[]{}), por lo que terminas pagando unos pocos bytes para codificar muy poca información. Una idea más inteligente, y la utilizada hasta ahora es asignar cada una de las 8 llaves a un número mucho menor (1-8) y convertirlas a los valores ASCII con nuestro decodificador. Esto es bueno porque no cuesta más de 18 bytes codificar un carácter en lugar de los 252 anteriores.

Sin embargo, este programa tampoco. Se basa en el hecho de que los programas Brain-Flak están todos equilibrados para codificar los 8 aparatos con los números hasta el 5. Los codifica de la siguiente manera.

(       -> 2
<       -> 3
[       -> 4
{       -> 5
),>,],} -> 1

Todas las llaves cerradas se asignan 1 porque podemos usar el contexto para determinar cuál de ellas necesitamos usar en un escenario particular. Esto puede sonar como una tarea desalentadora para un programa Brain-Flak, pero realmente no lo es. Tomemos, por ejemplo, las siguientes codificaciones con las llaves abiertas decodificadas y las llaves cerradas reemplazadas por a .:

(.
((..
<([.{...

Esperemos que pueda ver que el algoritmo es bastante simple, leemos de izquierda a derecha, cada vez que encontramos un paréntesis abierto empujamos su paréntesis cerrado a una pila imaginaria y cuando encontramos un .pop, colocamos el valor superior y lo colocamos en lugar del .. Esta nueva codificación nos ahorra una enorme cantidad de bytes en el codificador y solo nos pierde un puñado de bytes en el decodificador.

Explicación de bajo nivel

Trabajo en progreso

Sriotchilism O'Zaic
fuente
25
Creo que ganas por la solución más larga a un desafío de código de golf ...
Mego
18
Acabo de hacer el golf individual más grande en la historia de PPCG Nope. Sin embargo, 9.8e580 sigue siendo impresionante.
Dennis
19
+1 para encajar en el universo observable. Además, con TIO Nexus, el enlace permanente debería encajar en la respuesta. tio.run/nexus/…
Dennis
3
... golf muy grande ...
Destructible Lemon
3
Creo que ganas para la mayoría de los bytes cortados
Christopher
68

Preludio , 5157 4514 2348 1761 1537 664 569 535 423 241 214 184 178 175 169 148 142 136 133 bytes

Gracias a Sp3000 por guardar 3 bytes.

Esto es bastante largo ... (bueno, todavía es largo ... al menos está superando la quine Brainfuck C # más corta conocida en este desafío ahora) pero es la primera quine que descubrí (mis presentaciones de Lua y Julia son solo traducciones de técnicas estándar de quine en otros idiomas) y hasta donde yo sé, nadie ha escrito un quine en Prelude hasta ahora, por lo que estoy muy orgulloso de esto. :)

7( -^^^2+8+2-!( 6+ !
  ((#^#(1- )#)8(1-)8)#)4337435843475142584337433447514237963742423434123534455634423547524558455296969647344257)

Esa gran cantidad de dígitos es solo una codificación del código central, por lo que la cantidad es tan larga.

Los dígitos que codifican la quine se han generado con este script CJam .

Esto requiere un intérprete que cumpla con los estándares, que imprime caracteres (usando los valores como códigos de caracteres). Entonces, si está utilizando el intérprete de Python , deberá configurarlo NUMERIC_OUTPUT = False.

Explicación

Primero, algunas palabras sobre Prelude: cada línea en Prelude es una "voz" separada que manipula su propia pila. Estas pilas se inicializan a un número infinito de ceros. El programa se ejecuta columna por columna, donde todos los comandos de la columna se ejecutan "simultáneamente" en función de los estados anteriores de la pila. Los dígitos se insertan en la pila individualmente42 lo que presionarán a 4, luego a 2. No hay forma de empujar números más grandes directamente, tendrás que sumarlos. Los valores se pueden copiar de pilas adyacentes con vy ^. Los bucles de estilo Brainfuck se pueden introducir entre paréntesis. Vea el enlace en el título para más información.

Aquí está la idea básica de la quine: primero empujamos cargas de dígitos en la pila que codifican el núcleo de la quine. Dicho núcleo toma esos dígitos, los decodifica para imprimirse y luego imprime los dígitos a medida que aparecen en el código (y el final )).

Esto es un poco complicado por el hecho de que tuve que dividir el núcleo en varias líneas. Originalmente tenía la codificación al principio, pero luego necesitaba rellenar las otras líneas con el mismo número de espacios. Es por eso que las puntuaciones iniciales fueron tan grandes. Ahora he puesto la codificación al final, pero esto significa que primero necesito omitir el núcleo, luego presionar los dígitos y volver al inicio e imprimir.

La codificación

Dado que el código solo tiene dos voces, y adyacencia es cíclico, ^y vson sinónimos. Eso es bueno porque vtiene, con mucho, el código de caracteres más grande, por lo que evitarlo usando siempre ^hace que la codificación sea más simple. Ahora todos los códigos de caracteres están en el rango de 10 a 94, inclusive. Esto significa que puedo codificar cada carácter con exactamente dos dígitos decimales. Sin embargo, hay un problema: algunos caracteres, especialmente el salto de línea, tienen un cero en su representación decimal. Eso es un problema porque los ceros no se distinguen fácilmente del fondo de la pila. Afortunadamente, hay una solución simple para eso: compensamos los códigos de caracteres, por 2lo que tenemos un rango de 12 a 96, inclusive, que todavía cabe cómodamente en dos dígitos decimales. Ahora, de todos los personajes que pueden aparecer en el programa Preludio,0tiene un 0 en su representación (50), pero realmente no necesitamos 0nada. Así que esa es la codificación que estoy usando, empujando cada dígito individualmente.

Sin embargo, dado que estamos trabajando con una pila, las representaciones se envían en reversa. Entonces, si nos fijamos en el final de la codificación:

...9647344257

Divídase en pares e invierta, luego reste dos, y luego busque los códigos de caracteres:

57 42 34 47 96
55 40 32 45 94
 7  (     -  ^

donde 32es corresponde a espacios. El núcleo hace exactamente esta transformación y luego imprime los caracteres.

El núcleo

Así que veamos cómo se procesan realmente estos números. Primero, es importante tener en cuenta que los paréntesis coincidentes no tienen que estar en la misma línea en Prelude. Solo puede haber un paréntesis por columna, por lo que no hay ambigüedad en el paréntesis. En particular, la posición vertical del paréntesis de cierre es siempre irrelevante: la pila que se verifica para determinar si el ciclo termina (o se omite por completo) siempre será la que tenga el (.

Queremos ejecutar el código exactamente dos veces: la primera vez, omitimos el núcleo y presionamos todos los números al final, la segunda vez que ejecutamos el núcleo. De hecho, después de ejecutar el núcleo, presionaremos todos esos números nuevamente, pero dado que el ciclo termina después, esto es irrelevante. Esto le da el siguiente esqueleto:

7(
  (                   )43... encoding ...57)

Primero, empujamos un 7a la primera voz: si no hacemos esto, nunca entraríamos en el bucle (para el esqueleto, solo es importante que esto no sea cero ... por qué específicamente 7lo veremos más adelante) . Luego entramos en el bucle principal. Ahora, la segunda voz contiene otro bucle. En la primera pasada, este bucle se omitirá porque la segunda pila está vacía / contiene solo 0s. Entonces saltamos directamente a la codificación y empujamos todos esos dígitos a la pila. El 7que empujamos en la primera pila todavía está allí, por lo que el ciclo se repite.

Esta vez, también hay un 7en la segunda pila, por lo que ingresamos el bucle en la segunda voz. El bucle en la segunda voz está diseñado de modo que la pila esté vacía nuevamente al final, por lo que solo se ejecuta una vez. Será también agotar la primera pila ... Así que cuando dejamos el bucle de la segunda voz, que empujar todos los dígitos de nuevo, pero ahora el 7de la primera pila se ha descartado, por lo que los principales extremos del asa y el programa termina.

A continuación, veamos el primer bucle en el núcleo real. Hacer cosas simultáneamente con un (o )es bastante interesante. He marcado el cuerpo del bucle aquí con =:

-^^^2+8+2-!
(#^#(1- )#)
 ==========

Eso significa que la columna que contiene (no se considera parte del bucle (los caracteres allí solo se ejecutan una vez, e incluso si se omite el bucle). Pero la columna que contiene ) es parte del bucle y se ejecuta una vez en cada iteración.

Entonces comenzamos con un single -, que convierte el 7primer stack en un -7... otra vez, más sobre eso después. En cuanto al bucle real ...

El ciclo continúa mientras la pila de dígitos no se ha vaciado. Procesa dos dígitos a la vez. El propósito de este bucle es decodificar la codificación, imprimir el carácter y al mismo tiempo cambiar la pila de dígitos a la primera voz. Entonces esta parte primero:

^^^
#^#

La primera columna mueve el 1 dígito a la primera voz. La segunda columna copia los 10 dígitos a la primera voz y al mismo tiempo copia el dígito de 1 a la segunda voz. La tercera columna mueve esa copia de nuevo a la primera voz. Eso significa que la primera voz ahora tiene el 1 dígito dos veces y los 10 dígitos intermedios. La segunda voz tiene solo otra copia de los 10 dígitos. Eso significa que podemos trabajar con los valores en la parte superior de las pilas y asegurarnos de que quedan dos copias en la primera pila para más adelante.

Ahora recuperamos el código de caracteres de los dos dígitos:

2+8+2-!
(1- )#

La parte inferior es un pequeño bucle que solo disminuye los 10 dígitos a cero. Para cada iteración queremos agregar 10 a la parte superior. Recuerde que el primero 2no es parte del bucle, por lo que el cuerpo del bucle es en realidad el +8+2que agrega 10 (usando el 2empujado anteriormente) y empuja otro 2. Entonces, cuando terminamos con el bucle, la primera pila realmente tiene la base- Valor 10 y otro 2. Restamos ese 2 con -para tener en cuenta el desplazamiento en la codificación e imprimimos el carácter con !. El #just descarta el cero al final del bucle inferior.

Una vez que se completa este ciclo, la segunda pila está vacía y la primera pila contiene todos los dígitos en orden inverso (y a -7en la parte inferior). El resto es bastante simple:

( 6+ !
8(1-)8)#

Este es el segundo bucle del núcleo, que ahora imprime todos los dígitos. Para hacerlo, necesitamos 48 por cada dígito para obtener su código de carácter correcto. Hacemos esto con un ciclo simple que ejecuta 8tiempos y agrega 6cada vez. El resultado se imprime con !y 8al final es para la siguiente iteración.

¿Y qué hay del -7? Sí, 48 - 7 = 41cuál es el código de personaje de ). ¡Magia!

Finalmente, cuando terminamos con ese bucle, descartamos el 8que acabamos de presionar #para asegurarnos de dejar el bucle externo en la segunda voz. Empujamos todos los dígitos nuevamente y el programa termina.

Martin Ender
fuente
1
Escuchando Hello World in Fugue en este momento ... bastante pegadizo.
Robert Fraser
19
Martin, tienes que parar en alguna parte.
seequ
3
Me encanta que esto tenga más de 5000 bytes en total, más un reconocimiento a Sp3000 por guardar 3 de ellos.
Kamil Drakari
2
@KamilDrakari Sin embargo, esos fueron los últimos 3 bytes, por lo que es un gran problema. ;)
Martin Ender
57

Hexagonía , longitud lateral 11, 314 bytes

164248894991581511673077637999211259627125600306858995725520485910920851569759793601722945695269172442124287874075294735023125483.....!/:;.........)%'=a':\....................\...................\..................\.................\................\...............\..............\..$@.........\$><>'?2='%.<\:;_;4Q

Pruébalo en línea!


Versión antigua:

Hexagonía , longitud del lado 11, 330 bytes

362003511553420961423766261426252539048636523959468260999944549820033581478284471415809677091006384959302453627348235790194699306179..../:{;+'=1P'%'a{:..\.....................\...................\..................\.................\................\...............\..............\.............\!$><........\..@>{?2'%<......:;;4Q/

Pruébalo en línea!

Codificador: ¡ Pruébelo en línea!

El programa es más o menos equivalente a este código Python: ¡ Pruébelo en línea!

Código desplegado:

           3 6 2 0 0 3 5 1 1 5 5
          3 4 2 0 9 6 1 4 2 3 7 6
         6 2 6 1 4 2 6 2 5 2 5 3 9
        0 4 8 6 3 6 5 2 3 9 5 9 4 6
       8 2 6 0 9 9 9 9 4 4 5 4 9 8 2
      0 0 3 3 5 8 1 4 7 8 2 8 4 4 7 1
     4 1 5 8 0 9 6 7 7 0 9 1 0 0 6 3 8
    4 9 5 9 3 0 2 4 5 3 6 2 7 3 4 8 2 3
   5 7 9 0 1 9 4 6 9 9 3 0 6 1 7 9 . . .
  . / : { ; + ' = 1 P ' % ' a { : . . \ .
 . . . . . . . . . . . . . . . . . . . . \
  . . . . . . . . . . . . . . . . . . . \ 
   . . . . . . . . . . . . . . . . . . \  
    . . . . . . . . . . . . . . . . . \   
     . . . . . . . . . . . . . . . . \    
      . . . . . . . . . . . . . . . \     
       . . . . . . . . . . . . . . \      
        . . . . . . . . . . . . . \       
         ! $ > < . . . . . . . . \        
          . . @ > { ? 2 ' % < . .         
           . . . . : ; ; 4 Q / .          

Dos .s toma 1 bit. Cualquier otro carácter toma 1 bit y un dígito base-97.

Explicación

Haga clic en las imágenes para ampliarlas. Cada parte de la explicación tiene el código Python correspondiente para ayudar a comprender.

Parte de datos

En lugar de la compleja estructura se utiliza en algunas otras respuestas (con <, "y algunas otras cosas), acabo de dejar pasar la IP a través de la mitad inferior.

Datos

Primero, la IP atraviesa muchos números y no-op's ( .) y mirrors ( \). Cada dígito se agrega al número en la memoria, por lo que al final el valor de la memoria es igual al número al inicio del programa.

mem = 362003511...99306179

! lo imprime

stdout.write(str(mem))

y $salta por el siguiente >.

A partir de la <. Si el valor de la memoria memes falso ( <= 0es decir, la condición mem > 0no se cumple), hemos terminado de imprimir el programa y deberíamos salir. La IP seguiría el camino superior.

Salida

(deje que la IP se ejecute en todo el mundo durante aproximadamente 33 comandos antes de presionar el @(que termina el programa) porque colocarlo en cualquier otro lugar incurre en algunos bytes adicionales)

Si es cierto, seguimos el camino inferior, nos redireccionamos algunas veces y ejecutamos algunos comandos más antes de presionar otro condicional.

# Python                    # Hexagony
# go to memory cell (a)     # {
a = 2                       # ?2
# go to memory cell (b)     # '
b = mem % a                 # %

Ahora el recuerdo se ve así:

Mem1

Si el valor es verdadero:

if b > 0:

se ejecuta el siguiente código:

# Python                    # Hexagony
b = ord('Q')                # Q
b = b*10+4                  # 4
# Note: now b == ord('.')+256*3
stdout.write(chr(b%256))    # ;
stdout.write(chr(b%256))    # ;

Véase la explicación detallada de la Q4en respuesta HelloWorld Hexagony de MartinEnder . En resumen, este código se imprime .dos veces.

Originalmente planeé imprimir esto .una vez. Cuando se me ocurrió esto (imprimir .dos veces) e implementarlo, se guardaron unos 10 dígitos.

Entonces,

b = mem // a                # :

Aquí hay un hecho importante que me di cuenta de que me ahorró unos 14 dígitos: no es necesario que esté en el lugar donde comenzó.


Para entender lo que digo, tengamos una analogía BF. (omita esto si ya lo entendió)

Dado el código

while a != 0:
    b, a = a * 2, 0
    a, b = b, 0
    print(a)

Suponiendo que seamos ael valor de la celda actual y bel valor de la celda derecha, una traducción directa de esto a BF es:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
    >[-<+>]       # a, b = b, 0
    <.            # print(a)
]

Sin embargo, tenga en cuenta que no necesitamos estar en la misma posición todo el tiempo durante el programa. Podemos dejar que el valor de asea ​​lo que somos al comienzo de cada iteración, luego tenemos este código:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
                  # implicitly let (a) be at the position of (b) now
    .             # print(a)
]

que es varios bytes más corto.


Además, el comportamiento de envoltura de la esquina también me evita tener un \espejo allí; sin él, no sería capaz de ajustar los dígitos (+2 dígitos para \sí mismo y +2 dígitos para un no emparejado .a la derecha, sin mencionar el banderas)

(detalles:

  • La IP ingresa en la esquina inferior izquierda, hacia la izquierda
  • Se deforma en la esquina derecha, todavía se dirige hacia la izquierda
  • Se encuentra con un \reflejo, ahora se dirige hacia arriba
  • Entra en la esquina y se deforma nuevamente en la esquina inferior izquierda

)


Si el valor (de la operación mod 2 anterior) es falso (cero), entonces seguimos esta ruta:

# Python                 # Hexagony   # Memory visualization after execution
b = mem // a             # :          # click here
base = ord('a') # 97     # a
y = b % base             # '%
offset = 33              # P1
z = y + offset           # ='+
stdout.write(chr(z))     # ;          # click here
mem = b // base          # {:         # click here

No explicaré demasiado detallado aquí, pero el desplazamiento en realidad no es exactamente 33, pero es congruente con el 33mod 256. Y chrtiene una implícita % 256.

usuario202729
fuente
3
Hombre, eso es un montón de no-operaciones
Jo King
26
Me reí de "Para entender lo que digo, tengamos una analogía [BrainFuck]". Solo en PPCG ... :)
Lynn
2
Me desplacé como 3 veces hasta la parte superior de la respuesta para votar, solo para descubrir que ya lo hice ...
NieDzejkob
2
310 bytes aprovechando el nuevo espacio de acortar el número
Jo King
2
308 bytes sacando aún más espacio
Jo King
46

Vim, 11 bytes

q"iq"qP<Esc>hqP
  • iq"qP<Esc>: Inserte manualmente un duplicado del texto que debe estar fuera de la grabación.
  • q"y hqP: Grabe el interior directamente en el ""registro sin nombre , para que pueda pegarse en el medio. El hes el único reposicionamiento requerido; si lo coloca dentro de la macro, se pegará en el resultado.

Editar

Una nota sobre la grabación con q": El registro sin nombre ""es algo divertido. No es realmente un registro verdadero como los demás, ya que el texto no está almacenado allí. En realidad, es un puntero a otro registro (generalmente "-para eliminaciones sin nueva línea, "0para yanks o "1para eliminaciones con una nueva línea). q"rompe las reglas; en realidad escribe a "0. Si ""ya estaba apuntando a otro registro que no sea "0, q"se sobrescribirá "0pero ""no se modificará. Cuando inicia un Vim nuevo, ""apunta automáticamente "0, por lo que está bien en ese caso.

Básicamente, Vim es raro y con errores.

udioica
fuente
espera por qué esto no funciona para mí
Destructible Lemon
@DestructibleWatermelon No puedo decir con certeza, pero una explicación es muy probable. Probablemente debería haberlo tenido antes en el informe, ya que puede desanimar a la gente. Lee la edición.
udioica
probablemente deberías poner algo sobre cómo presionar yo algo antes de correr puede ayudar
Destructible Lemon
¿Por qué no usas para mostrar presionando la tecla <Esc>? Parte de este " Unicode Block" Control Pictures "
mbomb007
44
@ mbomb007 La <Esc>notación es estándar en las asignaciones de Vim ( :help <>) y eso es lo que utiliza vimgolf.com. Cualquier vimgolfer experimentado estará acostumbrado a leerlo. En cuanto al Unicode, tengo que entrecerrar los ojos para leer las pequeñas letras, y oscurecen el método de escribirlas y buscar el archivo de ayuda.
udioica
44

Cubix , 20 bytes

3434Qu$v@!<"OOw\o;/"

Casi tengo el \o/ ...

Neto :

    3 4
    3 4
Q u $ v @ ! < "
O O w \ o ; / "
    . .
    . .

Pruébalo en línea

Pruébalo aquí !

Notas adicionales

Historia de fondo

Después de estar impresionado al leer esta gran respuesta de @ ais523, comencé a pensar en seguir jugando al golf. Después de todo, había bastantes no-ops allí, y eso no se sentía muy comprimido. Sin embargo, como la técnica que usa su respuesta (y la mía también), requiere que el código abarque líneas completas, se necesitaba un ahorro de al menos 12 bytes. Hubo un comentario en su explicación que realmente me hizo pensar:

Sobre el tema de jugar golf más abajo en esta quine, [...] necesitaría otra [...] forma de representar la cara superior del cubo [...]

Entonces, de repente, cuando me puse de pie y me alejé para tomar algo de beber, me di cuenta: ¿Qué pasaría si el programa no usara códigos de caracteres, sino más bien números para representar la cara superior? Esto es especialmente corto si el número que imprimimos tiene 2 dígitos. Cubix tiene 3 instrucciones de un byte para empujar los números de dos dígitos: N, Sy Q, que empujan 10, 32y 34, respectivamente, por lo que este debe ser bastante golfy, pensé.

La primera complicación con esta idea es que la cara superior ahora está llena de números inútiles, por lo que ya no podemos usar eso. La segunda complicación es que la cara superior tiene un tamaño que es el tamaño del cubo al cuadrado, y necesitaba tener un tamaño par, de lo contrario un número también terminaría en la posición inicial del puntero de instrucción, lo que llevaría a una pila contaminada. Debido a estas complicaciones, mi código necesitaba caber en un cubo de tamaño 2 (que puede contener 'solo' 24 bytes, así que tuve que jugar al menos 21 bytes). Además, debido a que las caras superior e inferior no se pueden usar, solo tenía 16 bytes efectivos.

Entonces comencé eligiendo el número que se convertiría en la mitad de la cara superior. Comencé con N(10), pero eso no funcionó por el enfoque que estaba tomando para imprimir todo. De cualquier manera, comencé de nuevo y usé S(32) por alguna razón. Eso resultó en una quine adecuada, o eso pensé. Todo funcionó muy bien, pero faltaban las citas. Entonces, se me ocurrió que el Q(34) sería realmente útil. Después de todo, 34 es el código de caracteres de la comilla doble, que nos permite mantenerlo en la pila, ahorrando (2, en el diseño que utilicé entonces) bytes preciosos. Después de cambiar un poco la ruta IP, todo lo que quedaba era un ejercicio para completar los espacios en blanco.

Cómo funciona

El código se puede dividir en 5 partes. Los revisaré uno por uno. Tenga en cuenta que estamos codificando las caras intermedias en orden inverso porque el modelo de pila es el primero en entrar, el último en salir.

Paso 1: imprimir la cara superior

Las instrucciones irrelevantes han sido reemplazadas por no-ops ( .). El IP comienza la tercera línea, a la izquierda, apuntando hacia el este. La pila está (obviamente) vacía.

    . .
    . .
Q u . . . . . .
O O . . . . . .
    . .
    . .

La IP termina en la posición más a la izquierda en la cuarta línea, apuntando hacia el oeste, a punto de pasar a la posición más a la derecha en esa misma línea. Las instrucciones ejecutadas son (sin el carácter de flujo de control):

QOO
Q   # Push 34 (double quotes) to the stack
 OO # Output twice as number (the top face)

La pila contiene solo 34, que representan el último carácter de la fuente.

Paso 2: codifica la cuarta línea

Esto hace más o menos lo que espera que haga: codificar la cuarta línea. La IP comienza con la comilla doble al final de esa línea, y va hacia el oeste mientras empuja los códigos de caracteres de cada personaje en el que aterriza hasta que encuentra una comilla doble correspondiente. Esta doble comilla coincidente es también el último carácter en la cuarta línea, porque la IP se ajusta nuevamente cuando llega al borde izquierdo.

Efectivamente, la IP se ha movido una posición hacia la izquierda, y la pila ahora contiene la representación de la cuarta línea en códigos de caracteres y orden inverso.

Paso 3: empuje otra cita

Necesitamos impulsar otra cita, y ¿qué mejor manera que reciclarla Qal comienzo del programa al abordarla desde la derecha? Esto tiene la ventaja adicional de que la IP se encuentra directamente con la cita que codifica la tercera línea.

Aquí está la versión neta para este paso. Las instrucciones irrelevantes han sido reemplazadas por no-ops nuevamente, las no-ops que se ejecutan han sido reemplazadas por hashtags ( #) con fines ilustrativos y la IP comienza en el último carácter en la cuarta línea.

    . .
    . .
Q u $ . . . . .
. . w \ . . / .
    . #
    . #

La IP termina en la tercera línea en la primera instrucción, a punto de ajustarse al final de esa línea porque apunta hacia el oeste. Se exceden las siguientes instrucciones (excluyendo el flujo de control):

$uQ
$u  # Don't do anthing
  Q # Push the double quote

Esta comilla doble representa la que está al final de la tercera línea.

Paso 4: codificar la tercera línea

Esto funciona exactamente igual que el paso 2, así que busque una explicación.

Paso 5: imprima la pila

La pila ahora contiene las líneas cuarta y tercera, en orden inverso, por lo que todo lo que tenemos que hacer ahora es imprimirla. La IP comienza en la penúltima instrucción en la tercera línea, moviéndose hacia el oeste. Aquí está la parte relevante del cubo (nuevamente, las partes irrelevantes han sido reemplazadas por no-ops).

    . .
    . .
. . . v @ ! < .
. . . \ o ; / .
    . .
    . .

Este es un bucle, como habrás visto / esperado. El cuerpo principal es:

o;
o  # Print top of stack as character
 ; # Delete top of stack

El ciclo finaliza si el elemento superior es 0, lo que solo ocurre cuando la pila está vacía. Si el ciclo finaliza, @se ejecuta y finaliza el programa.

Luke
fuente
Ojalá pudiera votar más esto
MickyT
Las recompensas siempre son bienvenidas ;-)
Lucas
42

Javascript ES6 - 21 bytes

$=_=>`$=${$};$()`;$()

Yo llamo a esta quine "The Bling Quine".

A veces, tienes que jugar al golf con estilo.

Mama Fun Roll
fuente
¿ !$=_=>`!$=${$}()`()Te ahorra 2 bytes?
Downgoat
Invalid assignment left hand side. Ojalá funcionara :(
Mama Fun Roll
1
@ TùxCräftîñg eliminar paréntesis alrededor de los literales de plantilla solo funciona en funciones prototipo nativas, como Array.prototype.join.
Mama Fun Roll
2
Hmm, no estoy seguro. Escribí esto hace más de un año (se consideró válido en ese momento), y no he estado siguiendo los cambios de reglas de quine demasiado de cerca. Sin embargo, agregar alerto console.logdespués de la función de flecha y envolver la cadena de plantilla entre paréntesis funcionaría.
Mama Fun Roll
3
Además, si ejecuta esto en el concole, sobrescribe $ (función jQuery) en este sitio, y la función de votación positiva ya no funcionará. :)
Steven Palinkas
41

Brainf * ck (755 caracteres)

Esto se basa en una técnica desarrollada por Erik Bosman (ejbosman en cs.vu.nl). Tenga en cuenta que el "Quine de ESultanik!" ¡el texto es realmente necesario para que sea un quine!

->++>+++>+>+>++>>+>+>+++>>+>+>++>+++>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>++>>>+++>>>>>+++>+>>>>>>>>>>>>>>>>>>>>>>+++>>>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+>++>+++>>>+>+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>>+++++++++++++++>+++++++++++++>++++++>+++++++++++++++>++++++++++>+++>+++>++++>++++++++++++++>+++>++++++++++>++++>++++++>++>+++++>+++++++++++++++>++++++++>++++>++++++++++++>+++++++++++++++>>++++>++++++++++++++>+++>+++>++++>++++++>+++>+++++++++>++++>+>++++>++++++++++>++++>++++++++>++>++++++++++>+>+++++++++++++++>+++++++++++++
ESultanik's Quine!
+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]>>+[>]+++[++++++++++>++[-<++++++++++++++++>]<.<-<]
ESultanik
fuente
13
Esa es una forma inteligente de hacerlo.
Peter Olson
13
¿Como funciona?
orgulloso Haskeller
3
@proudhaskeller IIRC, la parte anterior ESultanik's Quine!configura la memoria como una codificación de pila ESultanik's Quine!y hacia adelante, con dos bytes de memoria para cada carácter (el valor ASCII se compensa desde 0x1F). El último bit de código recorre la memoria, primero reproduce mediante programación los ++>+++…códigos para cada carácter y luego imprime los caracteres.
ESultanik
44
@CatsAreFluffy ¡Se requieren para que sea una quine! Si bien es cierto que podrían eliminarse, también habría que cambiar el código anterior para mantener la propiedad quine.
ESultanik
1
Es verdad. También las líneas nuevas son necesarias.
CalculatorFeline
36

Hexagonia , longitud lateral 15 14 13 12, 616 533 456 383 bytes

Después de varios días de golf cuidadoso, reorganizando bucles y comenzando de nuevo, finalmente he logré llevarlo a un lado 12 hexágono.

1845711724004994017660745324800783542810548755533855003470320302321248615173041097895645488030498537186418612923408209003405383437728326777573965676397524751468186829816614632962096935858"">./<$;-<.....>,.........==.........<"......."">'....>+'\.>.........==........<"......"">:>)<$=<..>..............$..<"...."">\'Q4;="/@>...............<"....."">P='%<.>.............<"..!'<.\=6,'/>

Pruébalo en línea!

Desplegado:

            1 8 4 5 7 1 1 7 2 4 0 0
           4 9 9 4 0 1 7 6 6 0 7 4 5
          3 2 4 8 0 0 7 8 3 5 4 2 8 1
         0 5 4 8 7 5 5 5 3 3 8 5 5 0 0
        3 4 7 0 3 2 0 3 0 2 3 2 1 2 4 8
       6 1 5 1 7 3 0 4 1 0 9 7 8 9 5 6 4
      5 4 8 8 0 3 0 4 9 8 5 3 7 1 8 6 4 1
     8 6 1 2 9 2 3 4 0 8 2 0 9 0 0 3 4 0 5
    3 8 3 4 3 7 7 2 8 3 2 6 7 7 7 5 7 3 9 6
   5 6 7 6 3 9 7 5 2 4 7 5 1 4 6 8 1 8 6 8 2
  9 8 1 6 6 1 4 6 3 2 9 6 2 0 9 6 9 3 5 8 5 8
 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
           ! ' < . \ = 6 , ' / > . .
            . . . . . . . . . . . .

Si bien no parece el código de Hexagony más desarrollado, el tipo de codificación que utilicé está optimizado para tiradas más largas de no-ops, que es algo que de otro modo evitarías.

Explicación

Esto supera la respuesta anterior de Hexagony al codificar las no-ops ( .) de una manera diferente. Si bien esa respuesta ahorra espacio al hacer que cada otro personaje sea a ., el mío codifica el número de no-ops. También significa que la fuente no tiene que ser tan restringida.

Aquí utilizo una codificación de base 80, donde los números por debajo de 16 indican carreras sin operaciones, y los números entre 16 y 79 representan el rango 32 ( !) a 95 ( _) (ahora me estoy dando cuenta de que saqué todos los _s de mi código lol). Algunos pseudocódigo Pythonic:

i = absurdly long number
print(i)
base = 80
n = i%base
while n:
    if n < 16:
        print("."*(16-n))
    else:
        print(ASCII(n+16))
    i = i//base
    n = i%base

El número está codificado en la primera mitad del hexágono, con todos los

" " > 
 " " > 
  ... etc

en el lado izquierdo y el

 > ,
< "
 >
< "
... etc

en el lado derecho redirigiendo el puntero para codificar el número en una celda. Esto está tomado de la respuesta de Martin Ender (gracias), porque no pude encontrar una manera más eficiente.

Luego ingresa a la sección inferior a través de ->:

       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
     ->    ! ' < . \ = 6 , ' / > . .

!imprime el número y 'navega a la celda de memoria correcta antes de comenzar el ciclo. P='%modifica el número actual en 80. Si el resultado es 0, sube hasta la terminación @, de lo contrario, baja y crea una celda junto al resultado de la modificación con el valor -16.

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
                      /
                     /

Establezca la celda en (valor de mod + -16). Si ese valor es negativo, suba en la bifurcación>+'\ , de lo contrario, baje.

Si el valor es positivo:

 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .

El puntero termina en el ;-< que establece la celda en (valor mod - -16) e imprime.

El valor es negativo:

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .

Baja a la > ) <sección que comienza el ciclo. Aquí está aislado:

     . . > ) < $ = < . .
      . . . . . . . . .
       \ ' Q 4 ; = " /

Que ejecuta el código 'Q4;="=que imprime un .(gracias de nuevo a Martin Ender, quien escribió un programa para encontrar las combinaciones de letras y números para los caracteres) y regresa a la celda inicial. Luego incrementa ( )) la celda de valor de mod y vuelve a recorrer, hasta que el valor de mod es positivo.

Cuando se hace eso, se mueve hacia arriba y se une con la otra sección en:

 " " > . / < $ ; - < . . .
            \
             \

El puntero luego regresa al inicio del bucle más grande nuevamente.

 " " > . / <--
  . . . = =
   . " " > ' 
    . . . = = 
     . " " > :
      . . . . .
       " " > \ ' . .
        . . . . . . .
         . . " " > P = ' % < . > . . .

Esto se ejecuta ='=:'y divide el número actual entre 80 y navega a la celda correcta.

Versión antigua (Longitud lateral 13)

343492224739614249922260393321622160373961419962223434213460086222642247615159528192623434203460066247203920342162343419346017616112622045226041621962343418346002622192616220391962343417346001406218603959366061583947623434"">/':=<$;'<.....>(......................<"......"">....'...>=\..>.....................<"....."">....>)<.-...>...........==......<"...."">.."...'.../>.................<"..."">\Q4;3=/.@.>...............<".."".>c)='%<..>..!'<.\1*='/.\""

Pruébalo en línea!

Definitivamente puedo jugar golf a otro lado de esto, pero tendré que dejarlo hasta mañana porque se está haciendo tarde. Resulta que soy impaciente y no puedo esperar hasta mañana. ¿Quizás otro lado puede jugar al golf? :( ahhhhhhhhh hice!

Incluso jugué un par de dígitos adicionales con una codificación base 77, pero en realidad no importa, ya que tiene el mismo bytecount.

Jo King
fuente
13
Esto es increíble. La idea de esta codificación híbrida de longitud de ejecución es realmente clara. :) Recuérdame darte una recompensa si lo olvido.
Martin Ender
35

PostScript, 20 caracteres

Corto y legítimo. 20 caracteres incluyendo nueva línea final.

(dup == =)
dup == =
KirarinSnow
fuente
33

Cubix , 45 bytes

.....>...R$R....W..^".<R.!'.\)!'"R@>>o;?/o'u"

Puedes probar este código aquí .

Este programa es bastante difícil de seguir, pero para tener alguna posibilidad de hacerlo, debemos comenzar expandiéndolo en un cubo, como lo hace el intérprete de Cubix:

      . . .
      . . >
      . . .
R $ R . . . . W . . ^ "
. < R . ! ' . \ ) ! ' "
R @ > > o ; ? / o ' u "
      . . .
      . . .
      . . .

Esta es una quine de estilo Befunge, que funciona mediante la explotación de la envoltura para hacer que los literales de cadena "envuelvan" el código ejecutable (con solo uno " marca, el código está dentro y fuera de la cita al mismo tiempo, algo que se hace posible cuando tienes programas que no son lineales y no planas). Tenga en cuenta que esto se ajusta a nuestra definición de una quine adecuada, porque dos de las comillas dobles no se codifican a sí mismas, sino que se calculan más tarde mediante el uso de la aritmética.

Sin embargo, a diferencia de Befunge, estamos usando cuatro cuerdas aquí, en lugar de una. Así es como son empujados a la pila;

  1. El programa comienza en la parte superior del borde izquierdo, yendo hacia la derecha; gira a la derecha dos veces ( R), haciéndolo ir hacia la izquierda a lo largo de la tercera y última línea que envuelve todo el cubo. La comilla doble coincide, por lo que empujamos toda la tercera línea hacia atrás en la pila. Luego, la ejecución continúa después de la doble cita.

  2. El ucomando hace un giro en U a la derecha, por lo que lo siguiente que estamos ejecutando es desde '"adelante en la línea media. Eso empuja un "sobre la pila. Continuando con la vuelta, golpeamos el <lado izquierdo del cubo y nos recuperamos. Cuando nos acercamos desde esta dirección, vemos un "comando simple , no '", por lo que toda la segunda línea se empuja hacia la pila hacia atrás por encima de la tercera línea y la comilla doble.

  3. Comenzamos empujando a !sobre la pila ( '!) e incrementándola ( )); esto produce una comilla doble sin necesidad de una comilla doble en nuestro código fuente (que terminaría la cadena). Un espejo ( \) refleja la dirección de ejecución hacia el norte; entonces el Wcomando se desvía hacia la izquierda. Esto nos deja yendo hacia arriba en la séptima columna, que debido a que es un cubo, se envuelve hacia la izquierda en la tercera fila, luego hacia abajo en la tercera columna. Tocamos un R, para girar a la derecha y avanzar hacia la izquierda a lo largo de la fila superior; luego $omite la Rvía por la que ingresamos al programa, por lo que la ejecución se ajusta al "final de la línea y capturamos la primera línea en una cadena de la misma manera que lo hicimos para el segundo y el tercero.

  4. El ^comando nos envía hacia el norte hasta la undécima columna, que está (permitiendo el ajuste del cubo) hacia el sur en la quinta. Lo único que encontramos allí es !(omitir si no es cero; la parte superior de la pila es de hecho distinta de cero), que omite el ocomando, haciendo que la quinta columna esté completamente vacía. Así que volvemos al ucomando, que una vez más gira en U, pero esta vez nos quedamos en la columna final hacia el sur, que se envuelve en la cuarta columna hacia el norte. Sin embargo, alcanzamos una comilla doble durante el giro en U, por lo que capturamos toda la cuarta columna en una cadena, de abajo hacia arriba. A diferencia de la mayoría de las comillas dobles en el programa, esta no se cierra sola; más bien, está cerrado por la "esquina superior derecha, lo que significa que capturamos la cadena de nueve caracteres ...>......

Entonces, el diseño de la pila es ahora, de arriba a abajo: cuarta columna; fila superior; "; fila del medio; "; fila inferior. Cada uno de estos se representa en la pila con el primer carácter más cercano a la parte superior de la pila (Cubix empuja cadenas en el reverso de este orden, como lo hace Befunge, pero cada vez que la IP se movía en la dirección opuesta a la dirección de lectura natural, por lo que efectivamente se invirtió dos veces). Se puede observar que el contenido de la pila es casi idéntico al programa original (porque la cuarta columna y la cara norte / superior del cubo contienen los mismos caracteres en el mismo orden; obviamente, fue diseñado así intencionalmente).

El siguiente paso es imprimir el contenido de la pila. Después de todos los empujes, la IP va hacia el norte en la cuarta columna, por lo que golpea >allí y entra en un bucle cerrado >>o;?(es decir, "gire hacia el este, gire hacia el este, salga como carácter, pop, gire a la derecha si es positivo"). Debido a que la séptima línea está llena de NOP, la ?va a volver a la primera >, por lo que esto empuja efectivamente todo el contenido de la pila ( ?es un no-op en una pila vacía). ¡Casi imprimimos todo el programa! Desafortunadamente, aún no está hecho; nos falta la comilla doble al final.

Una vez que finaliza el bucle, reflexionamos sobre la línea central, moviéndonos hacia el oeste, a través de un par de espejos. (Usamos el "otro lado" del \espejo antes; ahora estamos usando el lado suroeste. El /espejo no se ha usado antes). Encontramos '!, así que empujamos un signo de exclamación (es decir, 33; estamos usando ASCII y Cubix no distingue entre enteros y caracteres) en la pila. (Convenientemente, esto es lo mismo !que se usó para omitir el ocomando anterior). Nos encontramos con un par de Rcomandos y los usamos para hacer un giro en U "manual" (el segundo Rcomando aquí se usó antes para llegar al primero fila, por lo que parecía más natural encajar otro Rcomando junto a él.Wcomando, para esquivar a la izquierda. El paso lateral choca directamente con el>comando en la segunda línea, recuperando la ejecución exactamente donde estaba. Entonces, volvemos a la izquierda, pero esta vez vamos hacia el sur, por lo que el siguiente comando para ejecutar es )(incrementando el signo de exclamación en una comilla doble), seguido de un o(para generarlo). Finalmente, la ejecución se ajusta a lo largo de la octava línea a la segunda columna, donde encuentra una @para salir del programa.

Pido disculpas por el apóstrofe perdido en la tercera línea. No hace nada en esta versión del programa; Era parte de una idea anterior que tenía pero que resultó no ser necesaria. Sin embargo, una vez que obtuve un quine funcional, solo quería enviarlo en lugar de perder el tiempo con él, especialmente porque eliminarlo no cambiaría el recuento de bytes. Sobre el tema de jugar golf más abajo en esta línea, no me sorprendería si esto fuera posible en 3 × 3 usando solo las primeras cinco líneas, pero no puedo ver una manera obvia de hacerlo, y necesitaría un empaquetamiento aún más estricto de todo el flujo de control junto con alguna otra forma de representar la cara superior del cubo (o bien modificar el algoritmo para que pueda continuar usando la cuarta columna a pesar de que ahora tendría diez u once caracteres de longitud) .


fuente
Buen trabajo, este es un puntaje realmente impresionante. Me encanta cómo codificaste la cara superior. :)
Martin Ender
¡Esto es simplemente increíble! Si sería de ayuda, otra forma de presionar "es Q.
ETHproductions
1
¡Guauu! ¡Nunca pensé que vería un cubix quine!
FlipTack
3
No tuve tiempo de leer la explicación ayer, pero ahora que tengo ... Solo ... GUAU. No puedo creer cuántos personajes se usan para dos o incluso tres propósitos completamente diferentes. Este es probablemente el mejor programa de Cubix que he visto.
ETHproductions
Buena explicación.
Robert Fraser
33

Python 2, 30 bytes

_='_=%r;print _%%_';print _%_

Tomado de aquí

hallvabo
fuente
1
+1, superaste mi solución similar, así que la eliminé. Cabe señalar que esto solo funciona en Python 2.
nyuszika7h
2
Parece extraño con el nombre de la variable como _, pero se lee mejor si lo asigna a cualquier letra, es decir, s:s='s=%r;print s%%s';print s%s
Ehtesh Choudhury
55
Si esta solución no es su propia creación, debe hacerla Wiki de la comunidad. Además, el enlace está muerto.
mbomb007
1
Llego un poco tarde a la fiesta, pero ¿alguien puede explicar cómo funciona?
MadTux
99
Esto requiere un salto de línea final para ser válido. Tal como está, el código fuente no coincide con la salida.
Dennis
32

Vim, 17 , 14 pulsaciones de teclas

Alguien votó al azar esto, así que recordé que existe. Cuando lo volví a leer, pensé "¡Oye, puedo hacerlo mejor que eso!", Así que jugué dos bytes. Todavía no es el más corto, pero al menos es una mejora.


Durante mucho tiempo, me he estado preguntando si un vim quine es posible. Por un lado, debe ser posible, ya que vim se está completando. Pero después de buscar un vim quine durante mucho tiempo, no pude encontrarlo. Me hice encuentro este desafío PPCG , pero está cerrado y no exactamente sobre quines literales. Así que decidí hacer uno, ya que no pude encontrar uno.

Estoy realmente orgulloso de esta respuesta, debido a dos primicias :

  1. Esta es la primera quine que he hecho, y

  2. Que yo sepa, este es el primer mundo vim-quine del mundo que se publica! Podría estar equivocado sobre esto, así que si sabes de uno, por favor avísame.

Entonces, después de esa larga introducción, aquí está:

qqX"qpAq@q<esc>q@q

Pruébalo en línea!

Tenga en cuenta que cuando escribe esto, mostrará la <esc>pulsación de tecla como ^[. Esto todavía es preciso, ya que ^[representa 0x1B, que es escape en ASCII , y la forma en que vim representa internamente la <esc>clave.

También tenga en cuenta que probar esto podría fallar si carga una sesión vim existente. Escribí una respuesta de explicando que aquí , si quieres más información, pero básicamente necesitas iniciar vim con

vim -u NONE -N -i NONE

o escriba qqqantes de ejecutar esto.

Explicación:

qq                  " Start recording into register 'q'
  X                 " Delete one character before the cursor (Once we play this back, it will delete the '@')
   "qp              " Paste register 'q'
      Aq@q<esc>     " Append 'q@q' to this line
               q    " Stop recording
                @q  " Playback register 'q'

En una nota al margen, esta respuesta es probablemente un récord mundial para la mayoría de las 'q' en una respuesta PPCG, o algo así.

DJMcMayhem
fuente
1
2i2i<esc>está muy cerca Siento que debe haber algo que pueda hacer para que esto funcione.
Zwei
@zwei Lo sé, ¡está cerca que duele! En realidad, <Esc>está implícito en V, por lo que funciona . Desafortunadamente, también agrega una nueva línea, por lo que aún no la he publicado.
DJMcMayhem
q"iq"qbP<Esc>qbPes 11. Después de poner esto en reddit , investigué el vimgolf aquí y decidí hacer una cuenta. Esta es la respuesta que publiqué allí.
udioica
2
@udioica ¿Puedes publicar eso como respuesta?
DJMcMayhem
28

Perdido , 120116 98 96 76 70 66 bytes

Editar: yay, menos de 100

Editar: guardado un montón de bytes cambiando a todos los /s en la línea inferior

:2+52*95*2+>::1?:[:[[[[@^%?>([ "
////////////////////////////////

Pruébalo en línea! + verificación es determinista para todos los estados posibles

Lost es un lenguaje 2D en el que la posición y dirección de inicio son completamente aleatorias. Esto significa que debe haber una gran cantidad de verificación de errores en cada etapa para asegurarse de que tiene el puntero de instrucción correcto, y no es uno que se haya desplazado al azar.

Explicación:

Todos los /s en la línea inferior están ahí para asegurarse de que todos los punteros que se generan en una dirección vertical o en la línea inferior se canalicen en la dirección correcta. A partir de ahí, terminan en varios lugares diferentes, pero todos terminan yendo directamente a la

 ^%?>
 ////

Lo que borra todos los números que no son cero en la pila. El ([después de que borra cualquier 0s adicionales también.

En el medio del claro, golpea el %, lo que apaga la 'seguridad', lo que permite que el programa termine cuando golpea el @(sin esto, el programa podría terminar inmediatamente si un puntero se iniciara en el@ ).

A partir de ahí, hace una línea de lenguaje 2D bastante simple, al envolver un literal de cadena ( ") alrededor de la primera línea, empujar un "carácter al duplicar un espacio ( :2+) y luego una nueva línea ( 52*). Para la segunda línea, crea un /carácter ( 95*2+) y lo duplica un montón ( >::1?:[:[[[[), antes de terminar finalmente en @e imprimir la pila implícitamente. El ?1objetivo es evitar que el proceso cree demasiados ceros si el puntero ingresa temprano, ahorrando tener que borrarlos más tarde.

Ahorré 20 bytes aquí haciendo que la última línea tenga el mismo carácter, lo que significa que podría pasar directamente del proceso de duplicación al final @.

Explicación sobre el proceso de duplicación:

[es un personaje conocido como 'Puerta'. Si el puntero golpea el lado plano de a [o a ], se refleja, de lo contrario, lo atraviesa. Cada vez que el puntero interactúa con una puerta, cambia al tipo opuesto. Usando este conocimiento podemos construir una fórmula simple para cuántas veces se ejecutará una instrucción en un >:[bloque.

Agregue la cantidad inicial de instrucciones. Para cada uno [, agregue 2 veces la cantidad de instrucciones a la izquierda. Para el ejemplo >::::[:[[[, comenzamos con 5 como la cantidad inicial. La primera puerta tiene 4 instrucciones de duplicación, por lo que agregamos 4 * 2 = 8 a 5 para obtener 13. Las otras tres puertas tienen 5 duplicados a su izquierda, por lo que agregamos 3 * (5 * 2) = 30 a 13 para obtener 43 instrucciones duplicadas ejecutadas, y tienen 44 >s en la pila. El mismo proceso se puede aplicar a otras instrucciones, como( empujar una gran cantidad de elementos de la pila al alcance, o como se usa aquí, para borrar elementos de la pila.

Un truco que he usado aquí para evitar duplicar demasiados ceros es el 1?. Si el carácter es 0, ?no omite el 1, lo que significa que duplica 1 para el resto del engaño. Esto hace que sea mucho más fácil limpiar la pila más adelante.

Jo King
fuente
25

Estas son las dos quines rubí más cortas de SO :

_="_=%p;puts _%%_";puts _%_

y

puts <<2*2,2
puts <<2*2,2
2

No me preguntes cómo funciona el segundo ...

Nakilon
fuente
8
El segundo usa heredoc, <<2comienza una cadena en la siguiente línea y *2repite la cadena
Ming-Tang
¿Por qué necesitas el 2?
CalculatorFeline
1
@CalculatorFeline Es el terminador de la cadena heredoc (que tiene que aparecer en su propia línea). Sin embargo, en realidad no tiene que ser un 2: tio.run/##KypNqvz/v6C0pFjBxsZAy0jHgAuFY8D1/z8A
Martin Ender
25

Fisión , 6 bytes.

Parece que esta es la quine "adecuada" más corta entre estas respuestas.

'!+OR"

Explicación

El flujo de control comienza en Rcon un solo (1,0)átomo a la derecha . Se golpea "alternar el modo de impresión y luego se envuelve alrededor de la línea, la impresión'!+OR antes de llegar a la misma "de nuevo y salir del modo de impresión.

Eso deja el "mismo para ser impreso. La forma más corta es '"O(donde '"establece la masa del átomo en el código de caracteres "e Oimprime el carácter y destruye el átomo), pero si lo hiciéramos ", interferiría con el modo de impresión. Por lo tanto, establecemos el valor del átomo en '!(uno menos que "), luego incrementamos con +y luego imprimimos el resultado conO .

Alternativas

Aquí hay un par de alternativas, que son más largas, pero tal vez sus técnicas inspiren a alguien a encontrar una versión más corta usándolas (o tal vez sean más útiles en ciertas citas generalizadas).

8 bytes usando Jump

' |R@JO"

De nuevo, el código comienza en R. Los @intercambios de masa y energía para dar (0,1). Por lo tanto, Jhace que el átomo salte sobre la Orecta hacia ". Entonces, como antes, todos menos el "se imprimen en modo de cadena. Después, el átomo golpea |para invertir su dirección, y luego pasa a través de la '"Oimpresión ". El espacio es un poco molesto, pero parece necesario, porque de lo contrario ', el átomo trataría al |personaje como un personaje en lugar de un espejo.

8 bytes usando dos átomos

"'L;R@JO

Esto tiene dos átomos, comenzando desde la izquierda y desde la Lderecha R. El átomo de la izquierda obtiene su valor establecido por el '"cual se imprime inmediatamente con O(y el átomo destruido). Para el átomo de la derecha, intercambiamos masa y energía nuevamente, saltamos sobre el Opara imprimir el resto del código en modo de impresión. Posteriormente, su valor se establece por 'Lpero eso no importa porque el átomo se descarta con ;.

Martin Ender
fuente
Técnicamente inválido debido a la falta de separación de código / datos en la fuente.
CalculatorFeline
44
@CalculatorFeline '!+codifica ".
Martin Ender
No estoy familiarizado con la fisión, pero |R@JO"'funcionaría, ¿o aún necesitarías ese espacio después del '?
MildlyMilquetoast
1
@MistahFiggins Creo que sí, pero lo más importante es que imprimirías el 'primero.
Martin Ender
24

JavaScript de navegador cruzado (41 caracteres)

Funciona en los 5 principales navegadores web (IE> = 8, Mozilla Firefox, Google Chrome, Safari, Opera). Ingrese en la consola del desarrollador en cualquiera de esos:

eval(I="'eval(I='+JSON.stringify(I)+')'")

No es "trampa", a diferencia del quine de un solo byte de Chris Jester-Young, ya que podría modificarse fácilmente para usar la alert()función (que cuesta 14 caracteres):

alert(eval(I="'alert(eval(I='+JSON.stringify(I)+'))'"))

O convertido a un marcador (con un costo de 22 caracteres):

javascript:eval(I="'javascript:eval(I='+JSON.stringify(I)+')'")
Por favor levantese
fuente
24

C, 64 60 bytes

main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

Hasta ahora, esta es la quina C más corta conocida. Hay un recompensa extendida si encuentras una más corta.

Esto funciona en GCC , Clang y TCC en un entorno POSIX . Invoca una cantidad excesiva de comportamiento indefinido con todos ellos.

Solo por diversión, aquí hay un repositorio que contiene todas las C quines que conozco. No dude en bifurcar / PR si encuentra o escribe uno diferente que agrega algo nuevo y creativo sobre los existentes.

Tenga en cuenta que solo funciona en un entorno ASCII . Esto funciona para EBCDIC , pero aún requiere POSIX . Buena suerte para encontrar un entorno POSIX / EBCDIC de todos modos: P


Cómo funciona:

  1. main(s)abusa mainde los argumentos, declarando una variable prácticamente sin tipos . (Tenga en cuenta ques realidad no está sin tipo, pero dado que los compiladores enumerados lo autoemiten según sea necesario, también podría ser *).
  2. printf(s="..." conjuntos s en la cadena proporcionada y pasa el primer argumento a printf.
  3. s se establece en main(s){printf(s=%c%s%1$c,34,s);} .
  4. La %cesté configurado como ASCII 34, ". Esto hace posible la quine. Ahora se sve así:
    main(s){printf(s="%s%1$c,34,s);} .
  5. El %sse establece en ssí mismo, lo cual es posible debido a # 2. Ahora se sve así:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);} .
  6. El %1$cse establece en ASCII 34 ", printfel primer argumento **. Ahora se sve así:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
    ... que resulta ser el código fuente original.

* Ejemplo gracias a @Pavel
** primer argumento después del especificador de formato, en este caso,s . Es imposible hacer referencia al especificador de formato.


Creo que es imposible que esto se acorte con el mismo enfoque. Si se pudiera printfacceder al especificador de formato $, esto funcionaría para 52 bytes:

main(){printf("main(){printf(%c%0$s%1$c,34);}",34);}
MD XF
fuente
Aunque ciertamente no debería considerarse como competidor, el ganador del "Peor abuso de las reglas" del Concurso Internacional de Código C Ofuscado de 1994 , 1994_smr.c , es definitivamente más corto.
Rayo
@ Ray No está permitido. No es una quine adecuada por ninguna definición. Las reglas de quien fueron cambiadas debido a ese programa: P
MD XF
Estoy totalmente de acuerdo, pero es un truco lo suficientemente interesante que vale la pena mencionar cada vez que alguien menciona una quine más pequeña conocida, aunque solo sea por razones históricas.
Rayo
44
ses de tipo int, no una "variable sin tipo".
feersum
2
Todos estos compiladores aparentemente permiten la conversión implícita de un puntero a int. s=3obviamente no funcionaría porque necesita pasar la cadena dos veces printf.
feersum
24

Java, 528 bytes:

Una solución Java con un enfoque original:

import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp",36);int i=0;for(byte c:b.toByteArray()){if(++i==92)System.out.print(b.toString(36));System.out.print((char)c);}}}

en forma legible:

import java.math.*;
class a
{
    public static void main (String [] a)
    {
        BigInteger b=new BigInteger ("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp", 36); 
        int i=0; 
        for (byte c:b.toByteArray ())
        {
            if (++i==92) 
                System.out.print (b.toString (36)); 
            System.out.print ((char) c);
        }
    }
}
usuario desconocido
fuente
¿Como funciona?
Loovjo
1
@Loovjo: Similar a otras soluciones que cortan el código en dos partes e insertan toda la Cadena que representa el código nuevamente, pero todo el código no es solo una Cadena sino que está codificado como el número largo en la base 36 (26 caracteres alfabéticos + 10 dígitos).
usuario desconocido
1
Esto podría acortarse si pones if(++i==92),
tuskiomi
2
@tuskiomi: Gracias, abreviado para dos personajes
usuario desconocido
1
@userunknown En realidad, a*como la matriz no sale en Java, esa es C. Algunas otras partes del golf:, import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("abc",36);int i=0;for(int c:b.toByteArray())System.out.printf("%s%c",++i==92?b.toString(36):"",c);}}donde abcsería la cadena mágica recién calculada. En java 8+ también es posible cambiar class a{public static void maina interface a{static void main, y en Java 10+ también es posible cambiar import java.math.*;y BigInteger b=new BigInteger(a var b=new java.math.BigInteger(.
Kevin Cruijssen
23

Pollo , 7

chicken

No, esto no se repite directamente :)

Timtech
fuente
Maldición, me ganaste :)
Taconut
¡No tiene eco, es la cuerda chicken!
Erik the Outgolfer
No hay separación de código / datos y, por lo tanto, no es válido.
CalculatorFeline
10
@CalculatorFeline ¿Leíste las reglas?
Timtech
1
@JoKing No creo que esto sea inválido, porque las reglas del desafío solo prohíben las quines de longitud cero y trampa (leer su propio archivo fuente). Lo único que prohíbe las quines inadecuadas es una escapatoria estándar , excepto que las lagunas estándar generalmente no se consideran aplicables a las respuestas anteriores a ellas.
pppery
23

Retina , 20 14 9 7 bytes

Antes de comenzar, me gustaría mencionar la solución trivial de un archivo que contiene uno 0. En ese caso, Retina intentará contar las 0s en la entrada vacía, cuyo resultado también es 0. Sin embargo, no lo consideraría una quine adecuada.

Así que aquí hay uno apropiado:

>\`
>\`

Pruébalo en línea!

Alternativamente, podríamos usar en ;lugar de >.

Explicación

El programa consiste en un solo reemplazo que imprimimos dos veces.

En la primera línea, `separa la configuración de la expresión regular, por lo que la expresión regular está vacía. Por lo tanto, la cadena vacía (es decir, la entrada inexistente) se reemplaza con la segunda línea, textualmente.

Para imprimir el resultado dos veces, lo envolvemos en dos etapas de salida. El interno, \imprime el resultado con un salto de línea final, y el externo >, lo imprime sin uno.

Si está un poco familiarizado con Retina, es posible que se pregunte qué pasó con la salida implícita de Retina. La salida implícita de Retina funciona envolviendo la etapa final de un programa en una etapa de salida. Sin embargo, Retina no hace esto, si la etapa final ya es una etapa de salida. La razón de ello es que en un programa normal es más útil ser capaz de reemplazar la etapa de salida implícita con uno especial como \o ;para un solo byte (en lugar de tener que deshacerse de la implícita con la .bandera también). Desafortunadamente, este comportamiento termina costando dos bytes para la quine.

Martin Ender
fuente
20

Javascript (36 caracteres)

(function a(){alert("("+a+")()")})()

Esta es, AFAICT, la más corta javascript publicada hasta ahora.

Peter Olson
fuente
1
Eso es impresionante. Deberías explicar cómo funciona para mí 8- |
TehShrike
3
@TehShrike Sugerencia: puede ver el contenido de una función coercitándola a una cadena. Por ejemplo, si tiene una función a, puede acceder a su contenido llamando a.toString.
Peter Olson
77
Sin embargo, para ser pedante, esto es solo una quine si su implementación de JavaScript stringifica la función aexactamente de la misma manera que se ha escrito anteriormente. Sin embargo, es probable que la salida de este código sea una quine en cualquier implementación de JavaScript.
Ilmari Karonen
1
Aquí es el mismo Quine, 1 byte más corto: !function a(){alert("!"+a+"()")}().
Ismael Miguel
1
(a=()=>alert(($ {a})))()
Dennis C
19

GolfScript, 8 bytes

Siempre pensé que la cantidad más corta (verdadera) de GolfScript era de 9 bytes:

{'.~'}.~

Donde el avance de línea final es necesario porque GolfScript imprime un avance de línea final de forma predeterminada.

Pero acabo de encontrar una quine de 8 bytes, que funciona exactamente alrededor de esa restricción de salto de línea:

":n`":n`

Pruébalo en línea!

Entonces, el problema es que GolfScript no imprime un salto de línea final, sino que imprime el contenido nal final del programa. Es solo que ncontiene un salto de línea para empezar. Entonces, la idea es reemplazar eso con la cadena ":n`", y luego encadenarla, de modo que la copia en la pila se imprima con comillas y la copia almacenada en nimpresiones sin.

Como señaló Thomas Kwa, la quine CJam de 7 bytes también se puede adaptar a una solución de 8 bytes:

".p"
.p

Nuevamente, necesitamos el avance de línea final.

Martin Ender
fuente
66
Golfscript es raro.
CalculatorFeline
19

Laberinto , 124 110 53 bytes

Gracias a Sp3000 por jugar golf en 9 bytes, lo que me permitió jugar golf en otros 7.

44660535853919556129637653276602333!
1
:_98
/8 %
@9_.

Pruébalo en línea!

Explicación

Laberinto 101:

  • Labyrinth es un lenguaje 2D basado en pila. La pila no tiene fondo y está llena de ceros, por lo que saltar de una pila vacía no es un error.
  • La ejecución comienza desde el primer carácter válido (aquí arriba a la izquierda). En cada cruce, donde hay dos o más rutas posibles para que el puntero de instrucción (IP) tome, la parte superior de la pila se verifica para determinar a dónde ir después. Negativo es girar a la izquierda, cero es avanzar y positivo es girar a la derecha.
  • Los dígitos en el código fuente no presionan el número correspondiente; en su lugar, resaltan la parte superior de la pila y presionan n*10 + <digit>. Esto permite la acumulación fácil de grandes números. Para comenzar un nuevo número, use _, que empuja a cero.
  • " son no-ops.

Primero, explicaré una versión un poco más simple que es un byte más larga, pero un poco menos mágica:

395852936437949826992796242020587432!
"
:_96
/6 %
@9_.

Pruébalo en línea!

La idea principal es codificar el cuerpo principal de la fuente en un solo número, utilizando una base grande. Ese número puede imprimirse fácilmente antes de decodificarse para imprimir el resto del código fuente. La decodificación es simplemente la aplicación repetida de divmod base, donde imprime mody continúa trabajando con el divhasta su cero.

Al evitar {}, el código de caracteres más alto que necesitaremos es _(95) de modo que la base 96 sea suficiente (al mantener la base baja, el número al principio es más corto). Entonces, lo que queremos codificar es esto:

!
"
:_96
/6 %
@9_.

Al convertir esos caracteres en sus puntos de código y tratar el resultado como un número base 96 (con el dígito menos significativo correspondiente !y el más significativo ., porque ese es el orden en el que desensamblaremos el número), obtenemos

234785020242697299628949734639258593

Ahora el código comienza con un truco bastante bueno (si puedo decirlo) que nos permite imprimir la codificación y conservar otra copia para decodificar con muy poca sobrecarga: colocamos el número en el código al revés. Calculé el resultado con este script de CJam. Pasemos al código real. Aquí está el comienzo:

395852936437949826992796242020587432!
"

La IP comienza en la esquina superior izquierda, hacia el este. Mientras corre sobre esos dígitos, simplemente acumula ese número en la parte superior de la pila. El número en sí no tiene ningún sentido, porque es lo contrario de lo que queremos. Cuando la IP llega al !, eso saca este número de la pila y lo imprime. Eso es todo lo que hay para reproducir la codificación en la salida.

Pero ahora la IP ha llegado a un callejón sin salida. Eso significa que gira y ahora se mueve hacia el oeste (sin ejecutar de !nuevo). Esta vez, convenientemente, la IP lee el número de atrás hacia adelante, de modo que ahora el número en la parte superior de la pila hace codificar el resto de la fuente.

Cuando la IP ahora golpea la esquina superior izquierda nuevamente, esto no es un callejón sin salida porque la IP puede girar a la izquierda, así que lo hace y ahora se mueve hacia el sur. El "es un no-op, que necesitamos aquí para separar el número del bucle principal del código. Hablando de que:

...
"
:_96
/6 %
@9_.

Mientras la parte superior de la pila aún no sea cero, la IP se ejecutará a través de este código bastante denso en el siguiente bucle:

"
>>>v
^< v
 ^<<

O presentado linealmente:

:_96%._96/

La razón por la que toma esos turnos se debe a la semántica de flujo de control de Labyrinth. Cuando hay al menos tres vecinos a la celda actual, la IP girará a la izquierda con un valor de pila negativo, avanzará a cero y girará a la derecha con un valor de pila positivo. Si la dirección elegida no es posible porque hay un muro, la IP tomará la dirección opuesta (es por eso que hay dos giros a la izquierda en el código, aunque la parte superior de la pila nunca es negativa).

El código de bucle en sí es bastante sencillo (comprimirlo así de apretado no era y es donde está la contribución principal de Sp3000):

:    # Duplicate the remaining encoding number N.
_96  # Push 96, the base.
%.   # Take modulo and print as a character.
_96  # Push 96 again.
/    # Divide N by 96 to move to the next digit.

Una vez que Nllega a cero, el flujo de control cambia. Ahora, a la IP le gustaría avanzar directamente después /(es decir, al oeste), pero hay un muro allí. Entonces, si se da la vuelta (este), se ejecuta de 6nuevo. Eso hace que la parte superior de la pila sea positiva, por lo que la IP gira a la derecha (sur) y ejecuta el 9. La cima de la pila es ahora 69, pero lo único que nos importa es que sea positivo. El IP toma otro giro a la derecha (oeste) y se mueve hacia el@ que termina el código.

En general, bastante simple en realidad.

Bien, ahora, ¿cómo podemos eliminar ese byte adicional? Claramente, ese no-op parece un desperdicio, pero necesitamos esa fila adicional: si el bucle fuera adyacente al número, la IP ya se movería allí inmediatamente en lugar de atravesar el número completo. Entonces, ¿podemos hacer algo útil con ese no-op.

Bueno, en principio podemos usar eso para agregar el último dígito a la codificación. La codificación realmente no necesita estar en la primera línea ... !solo garantiza que lo que sea que esté allí también se imprima allí.

Sin embargo, hay una trampa, no podemos simplemente hacer esto:

95852936437949826992796242020587432!
3
:_96
/6 %
@9_.

El problema es que ahora hemos cambiado el "a a 3, que también cambia el número real que queremos tener. Y efectivamente, ese número no termina en 3. Dado que el número está completamente determinado por el código a partir de, !no podemos hacer mucho al respecto.

¿Pero tal vez podamos elegir otro dígito? Realmente no nos importa si hay un 3punto en ese lugar siempre que terminemos con un número que codifique correctamente la fuente. Bueno, desafortunadamente, ninguno de los 10 dígitos produce una codificación cuyo dígito menos significativo coincide con el elegido. Afortunadamente, hay un margen de maniobra en el resto del código para que podamos probar algunas codificaciones más sin aumentar el recuento de bytes. He encontrado tres opciones:

  1. Podemos cambiar @a /. En ese caso, podemos usar cualquier dígito 1357y obtener una codificación coincidente. Sin embargo, esto significaría que el programa termina con un error, que está permitido pero no parece muy limpio.
  2. Los espacios no son los únicos caracteres de "muro". Cada carácter no utilizado es, en particular, todas las letras. Si usamos una letra mayúscula, entonces ni siquiera necesitamos aumentar la base para acomodarla (ya que esos puntos de código están debajo _). 26 opciones ofrecen muchas posibilidades. Por ejemplo, para Acualquier dígito impar funciona. Esto es un poco más agradable, pero aún no parece tan elegante, ya que nunca usarías una letra allí en código real.
  3. Podemos usar una base mayor. Mientras no aumentemos significativamente la base, el número de dígitos decimales en la codificación seguirá siendo el mismo (específicamente, cualquier base hasta 104 está bien, aunque las bases más allá de 99 en realidad requerirían caracteres adicionales en el propio código). Afortunadamente, la base 98 ofrece una única solución de coincidencia: cuando usamos el dígito 1, la codificación también termina 1. Esta es la única solución entre las bases 96, 97, 98, 99, por lo que es realmente muy afortunada. Y así es como terminamos con el código en la parte superior de esta respuesta.
Martin Ender
fuente
19

Perdido , 293 262 249 bytes

>:2+52*:6*:(84*+75*):>:::::[[[[[[[:[(52*)>::::[[[[[[:[84*+@>%?!<((((((((((([[[[[[[[[[[[[[ "
\#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\

Pruébalo en línea!

Explicación

Todo este proyecto ha sido de arriba abajo. Seguí pensando que era imposible y luego se me ocurrió una idea loca que podría funcionar.

¿Por qué es tan difícil una Quine perdida?

Como ya sabrás, Lost es un lenguaje de programación 2D en el que la ubicación y la dirección de inicio son completamente aleatorias. Esto hace que escribir cualquier programa perdido sea tan difícil como escribir código endurecido por radiación. Debe tener en cuenta todas las ubicaciones y direcciones posibles.

Dicho esto, hay algunas formas estándar de hacer las cosas. Por ejemplo, aquí está la forma estándar de imprimir una cadena.

>%?"Stringv"(@
^<<<<<<<<<<<<<

Esto tiene una secuencia de recopilación en la parte inferior que toma la mayor parte de los ips y los arrastra a la ubicación de inicio. Una vez que alcanzan su ubicación de inicio (arriba a la izquierda), los desinfectamos con un bucle, eliminando todos los valores en la pila, luego activamos la seguridad de empujar la cadena y salir. (la seguridad es un concepto exclusivo de Lost, cada programa debe golpear %antes de salir, esto evita la posibilidad de que el programa finalice al inicio). Ahora mi idea sería extender esta forma en una quine completa.

Lo primero que había que hacer era volver a trabajar un poco el bucle, el bucle existente era específico del formato de cadena.

>%?!<"Stringv"(@
^<<<<<<<<<<<<<<<
^<<<<<<<<<<<<<<<

Necesitamos agregar una segunda secuencia para evitar la posibilidad de !saltar sobre la secuencia y crear un bucle.

Ahora queremos mezclar esto con el formato estándar de Quine. Dado que Lost se basa mucho en Klein, básicamente he robado prestado el Klien Quine para Martin Ender .

:2+@>%?!< "
<<<<^<<<<<<
<<<<^<<<<<<

Esto imprime convenientemente la primera línea de la quine. Ahora todo lo que tenemos que hacer es codificar las transmisiones. Bueno, esto es más fácil decirlo que hacerlo. Probé aproximadamente cuatro métodos diferentes para hacer esto. Solo describiré el que funcionó.

La idea aquí es usar puertas para obtener el número deseado de flechas. Una puerta es un tipo especial de espejo que cambia cada vez que se golpea. [refleja los ips que vienen de la izquierda y ]de la derecha. Cuando son golpeados por una ip desde cualquiera de estos lados, la orientación del interruptor. Podemos hacer una línea de estas puertas y un reflector estático para realizar una operación repetidamente.

>:[[[

Realizará :tres veces. De esta manera, si empujamos un <a la pila de antemano, podemos hacer muchos de ellos con menos bytes. Hacemos 2 de estos, uno para cada línea, y entre ellos establecemos una nueva línea, sin embargo, el segundo solo necesita ir hasta que cubra el !que lo agregamos, cualquier otra cosa puede dejarse vacía ahorrándonos unos pocos bytes. Ok ahora necesitamos agregar las flechas verticales a nuestras transmisiones. Aquí es donde entra la optimización clave. En lugar de redirigir todos los ips al "inicio" del programa directamente, los redirigiremos al extremo izquierdo, porque ya sabemos que los ips que comienzan en el extremo izquierdo debentrabajo (o al menos funcionará en la versión final) también podemos redirigir los otros ips. Esto no solo lo hace más barato en bytes, creo que esta optimización es lo que hace posible la quine.

Sin embargo, todavía hay algunos problemas, el más importante es que los ips comienzan después de que >se ha presionado pero antes de comenzar a hacer copias de él. Tales ips entrarán en la copiadora y harán un montón de copias de 0. Esto es malo porque nuestro mecanismo de limpieza de la pila utiliza ceros para determinar la parte inferior de la pila, dejando un montón de ceros en la parte inferior. Necesitamos agregar un método de saneamiento de pila más fuerte. Como no hay una forma real de saber si la pila está vacía, simplemente tendremos que intentar destruir tantos elementos en la pila como sea posible. Aquí usaremos nuevamente el método de puerta descrito anteriormente. Vamos a añadir ((((((((((([[[[[[[[[[[[[[al final de la primera línea justo después de la sanitizor para deshacerse de los ceros.

Ahora hay un problema más, ya que redirigimos nuestras transmisiones a los ips superiores izquierdos comenzando en %y bajando ya habrá desactivado la seguridad y saldrá prematuramente. Por lo tanto, debemos desactivar la seguridad. Hacemos esto agregando un #a la secuencia, de esa manera los ips que fluyen a través de la secuencia se desactivarán pero los ips que ya han sido desinfectados no. El #también debe estar codificado en la primera línea también.

Eso es todo, espero que entiendas cómo funciona esto ahora.

Sriotchilism O'Zaic
fuente
: / tantos errores tipográficos y enlaces faltantes
solo ASCII
17

, 1165 879 606 561 540 522 498 + 7 = 505 bytes

Requiere la -cheatbandera para permitir la definición de alias.

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Pruébalo en línea!

Explicación

Hay dos partes en esto (como con la mayoría de las quines). Los datos:

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212

Y el decodificador:

=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Los datos son simplemente una codificación binaria del decodificador (o más bien su reverso). Cada uno 0comienza un nuevo carácter y las 1s y 2s son el 0- y 1-bits, respectivamente.

Tenga en cuenta que 0es un comando Yup estándar que empuja un cero, mientras que 1y 2no están definidos en este punto. Sin embargo, asignamos toda la parte de datos al comando %para que 1y 2pueda permanecer indefinido hasta que %se use realmente.

A continuación, definimos algunos comandos más:

0e-=<;
0<-=>;
:0~--=1;
1>=2;

<disminuye la parte superior de la pila, la >incrementa. 1(algo poco intuitivo) dobla la parte superior de la pila. 2lo duplica y luego lo incrementa. Gracias a estas definiciones, algo así 0221111dejará un 48 (110000 en binario) en la pila.

Los 32 bytes restantes realizan la decodificación real en dos partes. Primero necesitamos reconstruir la cadena de datos.

0%                ` Push a zero and then the data.
{                 ` For each value...
  {               `   Until that value is zero...
    >0<~{~>~<<}>  `   divmod 2. The div is the input to the next iteration,
                  `   the mod gives us the next bit.
    >>]           `   Increment twice (gives 2 or 3) and put at the bottom
                  `   of the stack.
  }
  >]              ` Increment the 0 and put it at the bottom as well.
}
$                 ` Reverse the entire stack.
{<#}              ` Decrement and print each number.

Y finalmente, empujamos los datos nuevamente e imprimimos cada valor como un carácter:

%{@}

Para referencia futura, aquí hay un script CJam para codificar los datos.

Martin Ender
fuente
17

Fueue , 423 bytes

Fueue es un esolang basado en cola en el que el programa en ejecución es la cola.

)$$4255%%1(~):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]](H-):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Pruébalo en línea!

Cómo funciona

Esta explicación puede o no haberse salido de control. Por otro lado, no sé cómo explicarlo mucho más brevemente de una manera que espero que la gente pueda seguir.

Fueue hoja de trucos

Consulte el artículo wiki de esolang para obtener detalles, incluidas las pocas funciones que no se utilizan en este programa.

  • El programa inicial es el estado inicial de la cola, que puede contener los siguientes elementos:

    • Los literales enteros (solo no negativos en la fuente, pero se pueden calcular los negativos), al ejecutarlos se imprime un carácter.
    • Bloques anidados delimitados por corchetes, inertes (conservados intactos a menos que alguna función actúe sobre ellos).
    • Funciones, sus argumentos son los elementos que los siguen inmediatamente en la cola:
      • +*/-%: aritmética de enteros ( -es unario, %negación lógica). Inerte si no se le dan argumentos numéricos.
      • ()<: coloca el elemento entre paréntesis, elimina los paréntesis del bloque, agrega el elemento final al bloque. Los dos últimos son inertes a menos que estén seguidos de un bloque.
      • ~:: intercambiar, duplicar.
      • $: copia (toma número + elemento). Inerte antes del no número.
      • H: detener el programa.

    Tenga en cuenta que si bien []anida, ()no lo haga; estas últimas son simplemente funciones separadas.

Sintaxis de seguimiento de ejecución

El espacio en blanco es opcional en Fueue, excepto entre números. En las siguientes trazas de ejecución se utilizará para sugerir la estructura del programa, en particular:

  • Cuando se ejecuta una función, ésta y sus argumentos se activarán a partir de los elementos circundantes con espacios. Si algunos de los argumentos son complicados, también puede haber un espacio entre ellos.
  • Muchos rastros de ejecución se dividen en un "blob de retraso" a la izquierda, separado de una parte a la derecha que realiza la manipulación sustancial de datos. Ver la siguiente sección.

Las llaves {}(no utilizadas en Fueue) se utilizan en las trazas para representar el resultado entero de las expresiones matemáticas. Esto incluye números negativos, ya que Fueue solo tiene literales no negativos: -es la función de negación.

Varios nombres metavariables y ...se utilizan para denotar valores y abreviaturas.

Tácticas dilatorias

Intuitivamente, la ejecución gira alrededor de la cola, modificando parcialmente lo que pasa. Los resultados de una función no se pueden volver a actuar hasta el próximo ciclo. Las diferentes partes del programa evolucionan efectivamente en paralelo siempre que no interactúen.

Como resultado, gran parte del código se dedica a la sincronización, en particular a retrasar la ejecución de partes del programa hasta el momento adecuado. Hay muchas opciones para jugar al golf, que tiende a convertir esas partes en gotas ilegibles que solo se pueden entender al rastrear su ejecución ciclo por ciclo.

Estas tácticas no siempre se mencionarán individualmente en lo siguiente:

  • )[A]retrasos Apara un ciclo. (Probablemente el método más fácil y más legible).
  • ~efintercambia los elementos ey feso también retrasa su ejecución. (Probablemente el menos legible, pero a menudo el más corto para retrasos menores).
  • $1eretrasa un solo elemento e.
  • -y %son útiles para retrasar números (este último para 0y 1.)
  • Al retrasar varios elementos iguales en una fila, :o $puede usarse para crearlos desde uno solo.
  • (nEnvolturas nentre paréntesis, que luego se pueden quitar a conveniencia. Esto es particularmente vital para los cálculos numéricos, ya que los números son demasiado inestables para ser copiados sin ponerlos primero en un bloque.

Estructura general

El resto de la explicación se divide en siete partes, cada una para una sección del programa en ejecución. Los ciclos más grandes después de los cuales la mayoría de ellos se repiten se denominarán "iteraciones" para distinguirlos de los "ciclos" de pasadas individuales en toda la cola.

Así es como se divide el programa inicial entre ellos:

A:  )$$4255%%1(~
B:  ):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
C:  
D:  (H-
E:  
F:  
G:  ):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

El gran número al final del programa codifica el resto en reversa, dos dígitos por carácter, con 30 restados de cada valor ASCII (por ejemplo, 10codifica a ().

En un nivel superior, puede pensar que los datos en este programa (comenzando con el bignum) fluyen de derecha a izquierda, pero el control fluye de izquierda a derecha. Sin embargo, en un nivel inferior, Fueue confunde la distinción entre código y datos todo el tiempo.

  • La sección G decodifica el bignum en dígitos ASCII (por ejemplo, un dígito 0como número entero 48), separando primero los dígitos menos significativos. Produce un dígito cada 15 ciclos.
  • La sección F contiene los valores ASCII de dígitos producidos (cada uno dentro de un bloque) hasta que la sección E pueda consumirlos.
  • La Sección E maneja los dígitos producidos de dos en dos, emparejándolos en bloques del formulario [x[y]], también imprime el carácter codificado de cada par.
  • La Sección D consiste en un bloque profundamente anidado construido gradualmente a partir de los [x[y]]bloques de tal manera que una vez que contiene todos los dígitos, se puede ejecutar para imprimirlos todos y luego detener todo el programa.
  • La sección C maneja la construcción de la sección D, y también recrea la sección E.
  • La sección B recrea la sección C, así como a sí misma, cada 30 ciclos.
  • La sección A cuenta los ciclos hasta la última iteración de las otras secciones. Luego aborta la sección B y ejecuta la sección D.

Sección a

La Sección A maneja la programación del final del programa. Se requieren 4258 ciclos para reducir a una sola función de intercambio ~, que luego realiza un ajuste en la sección B que detiene su bucle principal y comienza a ejecutar la sección D en su lugar.

)$ $4255% %1 (~
)$%%%...%% %0 [~]
)$%%%...% %1 [~]
⋮
)$ %0 [~]
) $1[~]
)[~]
~
  • Una $función crea 4255 copias de lo siguiente% mientras se (envuelve ~entre paréntesis.
  • Cada ciclo el último % se usa para alternar el siguiente número entre 0y 1.
  • Cuando todos los %s están agotados, el $1crea 1 copia del[~] (efectivamente un NOP), y en el siguiente ciclo, )elimina los corchetes.

Sección B

La sección B maneja la regeneración de sí mismo, así como una nueva iteración de la sección C cada 30 ciclos.

) : [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]            [BkB]
)$ $24%     %0  :<  [~:)~)]    ~ [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] [BkB]
)$ %...%%% %1   < < [~:)~)] [BkB]   [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...%% %0      < [~:)~)[BkB]] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...% %1         [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
⋮
) $1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                    (1)
~:) ~)[BkB]                 [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
) : [BkB]                 ) [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]      (2)
) [BkB] [BkB]               $11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<
  • A :duplica el siguiente bloque grande (una copia abreviada como[BkB] ), luego )elimina los corchetes de la primera copia.
  • $$24%%0 establece una cuenta regresiva similar a la de la sección A.
  • Mientras esto cuenta atrás, se :<convierte en <<y un~ cambia dos de los bloques, colocando el código para una nueva sección C al final.
  • Las dos <funciones empaquetan los dos bloques finales en el primero; esto es redundante en las iteraciones normales, pero permitirá~ sección A haga su trabajo al final.
  • (1) Cuando finaliza la cuenta regresiva, )elimina los corchetes externos. Luego se ~:)convierte ):y ~)cambia un) a al comienzo del código de la sección C.
  • (2) La sección B ahora está de vuelta en su ciclo inicial, mientras que a )está a punto de eliminar los corchetes para comenzar a ejecutar una nueva iteración de la sección C.

En la iteración final, la ~sección A aparece en el punto (1) anterior:

~ ) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                  (1)
[~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]              )

Los ~intercambios de) de todo el bloque y en la sección C, la prevención de la sección B se ejecute de nuevo.

Sección C

La Sección C maneja la fusión de nuevos pares de caracteres de dígitos en el bloque de la sección D, y también crea nuevas iteraciones de la sección E.

A continuación se muestra una iteración típica con xy que yrepresenta los códigos ASCII de los dígitos. En la primera iteración, los elementos entrantes "D" y "E" son los iniciales [H]y -, en cambio, como ninguna sección anterior E se ha ejecutado para producir ningún par de caracteres de dígitos.

C                                               D             E
$11~ )  ~<[[+$4--498+*-:~-10)):])<~]  [)))~]  < [)))~[...]]   [x[y]]
~~~ ~~~ ~~~ ~~) [[+$4--498+*-:~-10)):])<~]  < [)))~] [)))~[...][x[y]]]
~~~ ~~~     )  ~ [[+$4--498+*-:~-10)):])<~] [)))~[)))~[...][x[y]]]]
~~~       ~ )   [)))~[....]]                                  [[+$4--498+*-:~-10)):])<~]
                                              ~~[)))~[....]] )[[+$4--498+*-:~-10)):])<~]
                                                [)))~[....]]  ~[+$4--498+*-:~-10)):])<~
  • Esto usa un método diferente de sincronización que descubrí para esta respuesta. Cuando tiene varias funciones de intercambio ~en una fila, la fila se reducirá a aproximadamente 2/3 cada ciclo (porque uno ~intercambia dos siguientes), pero ocasionalmente con un resto de ~s que causa estragos manipula cuidadosamente lo que sigue.
  • $11~produce tal fila. El siguiente ~intercambia a a <través del siguiente bloque. Otro <al final agrega un nuevo bloque de pares de dígitos (dígitos x e y como códigos ASCII) en el bloque de la sección D.
  • El siguiente ciclo, la ~fila tiene un ~~resto, que intercambia un ~sobre el siguiente ). El otro <agrega la sección D a un [)))~]bloque.
  • A continuación, el intercambiado ~intercambia el siguiente bloque con el nuevo código de la sección E en el bloque de la sección D. Luego, un nuevo sobrante ~intercambia una )cruz y, finalmente, la última ~~de la ~fila intercambia una de ellas a la sección E justo cuando )ha eliminado sus corchetes.

En la iteración final, la sección A ~ha cambiado una )sección B a la sección C. Sin embargo, la sección C es tan efímera que ya ha desaparecido, y el) termina al principio de la sección D.

Sección D

La sección D se encarga de imprimir el número grande final y detener el programa. Durante la mayor parte de la ejecución del programa, es un bloque inerte que las secciones B – G cooperan en la construcción.

    (H -
    [H]-
    ⋮
    [)))~[H-]]                  After one iteration of section C
    ⋮
    [)))~[)))~[H-][49[49]]]]    Second iteration, after E has also run
    ⋮
)   [)))~[...]]     [49[48]]    Final printing starts as ) is swapped in
    ))) ~[...][49[48]]
    )) )[49[48]] [...]
    )) 49 [48][...]             Print first 1
    ) )[48] [...]
    ) 48 [...]                  Print 0
    )[...]                      Recurse to inner block
    ...
    ⋮
    )[H-]                       Innermost block reached
    H -                         Program halts
  • En el primer ciclo del programa, a (envuelve la función de detención Hentre paréntesis. UNA- continuación, se utilizará como un elemento ficticio para la primera iteración en lugar de un par de dígitos.
  • El primer par de dígitos real incorporado es el [49[49]]correspondiente al final 11en el número.
  • El último par de dígitos [49[48]](que corresponde al 10principio del número) no se incorpora realmente al bloque, pero esto no hace ninguna diferencia como )[A[B]]y )[A][B]son equivalentes, ambos se convierten en A[B].

Después de la iteración final, )llega el intercambio hacia la derecha desde la sección B y se desbloquea el bloque de la sección D. El )))~principio de cada subbloque asegura que todas las partes se ejecuten en el orden correcto. Finalmente, el bloque más interno contiene una Hdetención del programa.

Sección E

La sección E maneja la combinación de pares de dígitos ASCII producidos por la sección G, y ambos imprimen el carácter codificado correspondiente y envían un bloque con el par combinado hacia la izquierda a las secciones C y D.

Nuevamente, a continuación se muestra una iteración típica con xy que yrepresenta los códigos ASCII de los dígitos.

E                                                   F
~ [+$4--498+*-:~-10)):] )              <  ~         [y] [x]
) [+$4--498+*-:~-10)):]                   < [x] [y]
+ $4-  - 498  +*- :~ -10 ) )              : [x[y]]
+---  -{-498} +*- ~~{-10} )       ) [x[y]]  [x[y]]
+--    - 498  +*   -{-10}       ~ ) x  [y]  [x[y]]
+-    -{-498} +               * 10 x  )[y]  [x[y]]
+      - 498                    + {10*x} y  [x[y]]
                         + {-498} {10*x+y}  [x[y]]
{10*x+y-498}  [x[y]]
[x[y]]
  • Los bloques de dígitos entrantes se intercambian, luego el bloque y se agrega al bloque x, y se copia todo el bloque de pares. Se dejará una copia hasta el final para las secciones C y D.
  • La otra copia se desbloquea nuevamente, luego se aplica una secuencia de funciones aritméticas para calcular 10*x+y-498el valor ASCII del carácter codificado. 498 = 10*48+48-30, 48s deshace la codificación ASCII de xy ymientras 30cambia la codificación de 00–99a 30–129, que incluye todos los ASCII imprimibles.
  • El número resultante se deja ejecutar, lo que imprime su carácter.

Seccion F

La sección F consta de bloques inertes que contienen códigos ASCII de dígitos. Para la mayor parte de la ejecución del programa, habrá como máximo dos aquí, ya que la sección E los consume a la misma velocidad con la que G los produce. Sin embargo, en la fase de impresión final 0, aquí se acumularán algunos dígitos redundantes .

[y] [x] ...

Seccion G

La Sección G maneja la división del gran número al final del programa, los dígitos menos significativos primero, y el envío de bloques con sus códigos ASCII a la izquierda a las otras secciones.

Como no tiene verificación de detención, en realidad continuará produciendo 0dígitos cuando el número se haya reducido a 0, hasta que la sección D detenga todo el programa con la Hfunción.

[BkG] abrevia una copia del gran bloque de código de inicio, que se utiliza para la autorreplicación para iniciar nuevas iteraciones.

Inicialización en los primeros ciclos:

) :~  : [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  ( 106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
)  ~ ~ [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  [BkG] [10...11]
) [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]     ~ [BkG] [10...11]
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]       ~ : [10...11]  [BkG]

Iteración típica, Ndenota el número para dividir:

) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]        ~ : [N]  [BkG]
) :~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+ :5 )         : [N]  : [BkG]
)  ~ ~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]  +5 5     ) [N]  [N] [BkG] [BkG]
) [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]               ~ 10 N  [N] [BkG] [BkG]
) ~:~  ~ ( [:~)*[):~[$1(+48]):~+]-:~~)10)~~]               / N 10  [N] [BkG] [BkG]
)  ~ : [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                 ( {N/10}  [N] [BkG] [BkG]
) [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                    : [{N/10}]  [N] [BkG] [BkG]
:~ )*[):~[$1(+48]):~+]- :~ ~)10 )           ~ ~ [{N/10}]  [{N/10}] [N] [BkG] [BkG]
~~) *[):~[$1(+48]):~+]- ~~10 )             ) [{N/10}]  ~ [{N/10}] [N]  [BkG] [BkG]
)  ~ * [):~[$1(+48]):~+]  -10            ~ ) {N/10}  [N] [{N/10}] [BkG] [BkG]
) [):~[$1(+48]):~+]               * {-10} {N/10}  ) [N]  [{N/10}] [BkG] [BkG]
) :~ [$1(+48]) :~                 + {-10*(N/10)} N  [{N/10}] [BkG] [BkG]
)  ~ ~ [$1(+48]  )                 ~ ~ {N%10}  [{N/10}] [BkG] [BkG]
) [$1(+48]                 ~ ) {N%10}  ~ [{N/10}] [BkG]  [BkG]
$1(                     + 48 {N%10}    ) [BkG]  [{N/10}] [BkG]
                        ( {48+N%10}   BkG [{N/10}] [BkG]            New iteration starts
                        [{48+N%10}]   ....
  • La gota de retraso aquí es particularmente peluda. Sin embargo, el único nuevo truco de demora es usar en +:5lugar de --10retrasar 10dos ciclos. Por desgracia, solo uno de los 10s en el programa fue ayudado por esto.
  • Los bloques [N]y [BkG]se duplican, luego una copia de Nse divide por10 .
  • [{N/10}]se duplica, luego se utilizan más funciones aritméticas para calcular el código ASCII del último dígito de Nas 48+((-10)*(N/10)+N). El bloque con este código ASCII se deja para la sección F.
  • La otra copia de [{N/10}]se intercambia entre los [BkG]bloques para configurar el inicio de una nueva iteración.

Bonus quine (540 bytes)

)$$3371%%1[~!~~!)!]):[)$$20%%0[):]~)~~[)$$12%%0[<$$7%~~0):~[+----48+*-~~10))]<]<~!:~)~~[40~[:~))~:~[)~(~~/[+--48):]~10]+30])):]]][)[H]](11(06(06(21(21(25(19(07(07(19(61(96(03(96(96(03(11(03(63(11(28(61(11(06(06(20(18(07(07(18(61(11(28(63(96(11(96(96(61(11(06(06(19(20(07(07(18(61(30(06(06(25(07(96(96(18(11(28(96(61(13(15(15(15(15(22(26(13(12(15(96(96(19(18(11(11(63(30(63(30(96(03(28(96(11(96(96(61(22(18(96(61(28(96(11(11(96(28(96(61(11(96(10(96(96(17(61(13(15(15(22(26(11(28(63(96(19(18(63(13(21(18(63(11(11(28(63(63(63(61(11(61(42(63(63

Pruébalo en línea!

Como no estaba seguro de qué método sería el más corto, primero intenté codificar caracteres como números de dos dígitos separados por (s. El código central es un poco más corto, pero la representación de datos un 50% más grande lo compensa. No tan golfizado como el otro, ya que me detuve cuando me di cuenta de que no lo superaría. Tiene una ventaja: no requiere una implementación con soporte bignum.

Su estructura general es algo similar a la principal. Falta la sección G ya que la representación de datos completa la sección F directamente. Sin embargo, la sección E debe hacer un cálculo divmod similar para reconstruir los dígitos de los números de dos dígitos.

Ørjan Johansen
fuente
1
Deberías jugar golf la explicación XD
VFDan
1
)$n[)](es un byte más corto para el contador de retardo.
jimmy23013
15

Jalea, 3 bytes

”ṘṘ

Pruébalo en línea!

Verificación

$ echo $LANG
en_US
$ xxd -g 1 quine.jelly
0000000: ff cc cc                                         ...
$ ./jelly f quine.jelly | xxd -g 1
0000000: ff cc cc                                         ...

Cómo funciona

”ṘṘ    Main link. No input.

”Ṙ     Set the return value to the character 'Ṙ'.
  Ṙ    Print a string representation of the return value.
       This prints: ”Ṙ
       (implicit) Print the return value.
       This prints: Ṙ
Dennis
fuente
¿Qué versión del intérprete usa esto? Cuando lo pruebo, sale en UTF-8 a pesar de que la entrada está en la página de códigos de Jelly (y el cambio en la codificación haría que no sea una quine).
1
La codificación de la salida depende de la configuración de su terminal: si está configurada en UTF-x, la usa; si está configurado para otra cosa, usa la página de códigos de Jelly. En Linux,LANG=en_US logra eso. tio.run/nexus/bash#@@/…
Dennis