Escriba el programa de autoidentificación más corto (una variante quine)


57

Escriba un programa que generará una salida "verdadera" si la entrada coincide con el código fuente del programa, y ​​que genera una salida "falsa" si la entrada no coincide con el código fuente del programa.

Este problema puede describirse como relacionado con quines, ya que el programa debe poder calcular de alguna manera su propio código fuente en el proceso.

Este es el código de golf: se aplican reglas estándar. Su programa no debe acceder a ningún archivo especial, como el archivo de su propio código fuente.

Editar: si así lo elige, verdadero / falso se puede reemplazar con Verdadero / Falso o 1/0.

Ejemplo

Si el código fuente de su programa es bhiofvewoibh46948732));:/)4, entonces esto es lo que debe hacer su programa:

Entrada (Stdin)

bhiofvewoibh46948732));:/)4

Salida (Stdout)

true

Entrada

(Anything other than your source code)

Salida

false

77
¿El true/ falseoutput es un requisito fuerte, o también son aceptables las variaciones ( True/ False, 1/ 0)?
Cristian Lupascu

¿Es un problema si el programa genera un poco más de verdadero / falso (si sigue siendo inequívoco y termina con verdadero / falso)?
Denys Séguret


55
¿Te refieres a un programa narcisista?
PyRulez

Respuestas:



19

JavaScript ES6, 9 caracteres

Esta es la única forma (de golf) de hacerlo en JS. ES6 solo hace que tome menos personajes

Ejecute esto en la última consola web de Firefox:

f=x=>f==x

Ejemplo de uso:

f("check") // returns false
f("x=>f==x") // returns true

1
@phinotpi: ¿mi entrada sigue siendo elegible para ser seleccionada como respuesta?
Optimizador

66
Sin embargo, podría argumentarse que la fuente en este caso es f=x=>f==xy no x=>f==x, mientras que la versión de Denys Séguret verifica toda la fuente.
Hankrecords

@Hankrecords Deje que JavaScript decida eso. f=x=>f==x function f() f.toSource() "x=>f==x"(básicamente evalúe el código en la consola y luego evalúe f.toSource()en un navegador que admita ese método.
Optimizer

¿No se permiten funciones anónimas (acorte su código a x=>f==x) EDITAR: no importa, se hace referencia a f dentro de la función
MilkyWay90

9

Haskell, 72 caracteres

main=interact$show.(==s++show s);s="main=interact$show.(==s++show s);s="

Nota: no hay un carácter de final de línea al final del guión.

$ runhaskell Self.hs < Self.hs
True

8

GolfScript, 11 caracteres

{`".~"+=}.~

Sin el =, este código sería una quine que genera su propio código fuente como una cadena. Esto =hace que compare esta cadena con su entrada y salida 1si coinciden y 0si no. Tenga en cuenta que la comparación es exacta; en particular, una nueva línea final al final de la entrada hará que falle.

Explicación:

  • { } es un bloque de código literal en GolfScript;
  • .duplica este bloque de código y ~ejecuta la segunda copia (dejando la primera en la pila);
  • `stringifica el bloque de código y ".~"+ le agrega .~;
  • finalmente, =compara la cadena resultante con la entrada (que el intérprete de GolfScript empuja en la pila como una cadena antes de que comience el programa) y devuelve 1si coinciden y 0si no lo hacen.

7

Perl, Infinity 41 38 Personajes

$_=q(print<>eq"\$_=q($_);eval"|0);eval

Actualización: el programa ya no termina con una nueva línea, lo que significa que funcionará correctamente en archivos de varias líneas. Debe ingresar la entrada de STDIN sin presionar enter. En Windows solo pude hacer esto leyendo un archivo.

Solución original:

print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(...

1
¡Bien hecho! . . .
mafia

No se puede obtener un archivo que comienza con el código, por ejemplo(cat id.pl; echo foo)|perl id.pl
Geoff Reedy

@ GeoffReedy, gracias; el programa no manejaba la entrada multilínea antes. Está corregido ahora.

Maldición, ¿este código es boliche?
Matthew Roh el

7

> <> , 68 bytes

A los peces les encanta comer caca de pescado. Ahora sabemos que pueden distinguir los suyos de los de sus amigos.

00v      0+1~$^?)0~\;n0\
  >:@@:@gi:0(?\:a=?/=?!/$1+
  0n;n*=f$=2~~/

¡Puedes probarlo en línea !


1
Esto también da salida 1a cualquier prefijo del código
Jo King

@JoKing fue peor que solo prefijos del script, ¡también aceptó líneas truncadas! Lo arreglé, pero estoy decepcionado de que no sea tan genérico como quería que fuera, tuve que verificar la celda alcanzada al final del script para asegurarme de que todo el código coincidía. Ciertamente se puede mejorar, pero no estoy seguro de que me moleste.
Aaron

6

Pitón 2, 55

a='a=%r;print a%%a==raw_input()';print a%a==raw_input()

Probado:

a='a=%r;print a%%a==raw_input()';print a%a==raw_input() -> True

(anything else) -> False


3
Falla en cualquier archivo que comience con la primera línea igual a a='a=%r;print a%%a==raw_input()';print a%a==raw_input().
stand

Es cierto que no se admite la entrada multilínea.
flornquake

Una solución trivial sería reemplazar raw_input()con __import__('sys').stdin.read().
feersum

Estoy confundido por la redacción del desafío (porque no soy bueno con la gramática inglesa). ¿Esto está permitido? print raw_input()==open(__file__).read()? Tiene solo 40 bytes, usa su raw_input()enfoque, pero lee su código.
Simon

1
@Simon Eso no está permitido, es una de las lagunas estándar para desafíos como este. Y sí, esto es lo que significaYour program must not access any special files, such as the file of its own source code.
PunPun1000

6

JavaScript ES6, 16 14 bytes

$=_=>_==`$=`+$

Menos dos bytes gracias a Neil.

31 bytes si debemos tomar la entrada a través del indicador.

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

38 bytes si debemos emitir mediante alerta.

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

Esta es la forma correcta de hacerlo, ya que la respuesta de Optimizer no acepta todo el código fuente.


1
Bien, aunque solo escribiría '$='+$.
Neil

Oh verdad. @Neil
Conor O'Brien

1
Estoy bastante seguro de que necesita el final ;$()porque la llamada a la función es parte de la quine. Esto también significa que deberá cambiar a promptpara tener en cuenta la entrada.
Mama Fun Roll

1
Ese no es el problema. La llamada a la función es necesaria porque es parte de la quine. Permitir que el usuario lo llame como una función arruinaría la quine.
Mama Fun Roll

1
prueba$=_=>prompt()==`$=${$};$()`;$()
Mama Fun Roll

5

Nodo.js: 54

function f(){console.log(f+'f()'==process.argv[2])}f()

Lo prueba guardándolo en un archivo f.js(el nombre exacto no tiene importancia) y usando

node f.js "test"

(que da como resultado falso) o

node f.js "$(< f.js)"

(que da como resultado verdadero)

También hice una versión diferente basada en eval:

eval(f="console.log('eval(f='+JSON.stringify(f)+')'==process.argv[2])")

Ahora son 72 caracteres, intentaré acortar eso cuando tenga tiempo.


1
@ dan1111 ¿Por qué? No accede a ningún archivo. Solo estaba señalando cómo iniciar el programa a personas que no están acostumbradas a node.js. No lee el archivo.
Denys Séguret

1
Todas las soluciones Javascript aprovechan el hecho de que puede acceder a su propio código fuente en JS. Eso puede no ser técnicamente "acceder al archivo de su propio código fuente", pero logra exactamente lo mismo. Sin embargo, supongo que su respuesta es legal, ya que la pregunta no lo prohibió específicamente.

Bueno, accedes a la fuente de una función (solo el cuerpo para ser precisos) que es parte del programa. Eso es como usar mixin () en D. Sin embargo, no creo que las otras dos respuestas de JS, incluida una de mí, realmente califiquen como "programas".
Denys Séguret

@dystroy, en realidad, mezclar en D es más como usar eval que leer la fuente
fanático del trinquete el

@ratchetfreak sí, tienes razón. Pero creo que su programa utiliza una especie de toString del valor de enumeración, ¿verdad? Y cualquier código que use eval / mixin tiene el mismo truco que usar la fuente de la función.
Denys Séguret

5

Smalltalk (dialecto Pharo 2.0)

Implemente este método de 41 caracteres en String (formato feo para code-golf):

isItMe^self=thisContext method sourceCode

Luego evalúe esto en un área de trabajo (printIt en la forma tradicional de Smalltalk)
La entrada no se lee desde stdin, es solo una cadena a la que enviamos el mensaje (¿qué más podría ser un programa en Smalltalk?):

'isItMe^self=thisContext method sourceCode' isItMe.

Pero estamos haciendo trampa, sourceCode lee algún archivo fuente ...
Aquí hay una variante con 51 caracteres que no:

isItMe
    ^ self = thisContext method decompileString

Y prueba con:

'isItMe
    ^ self = thisContext method decompileString' isItMe

Si una cadena en un espacio de trabajo no se considera una entrada válida, entonces veamos cómo usar algunos cuadros de diálogo en 116 caracteres.
Solo evalúe esta oración:

(UIManager default request: 'type me') = (thisContext method decompileString withSeparatorsCompacted allButFirst: 7)

Como el formato de descompilación incluye CR y TAB, cambiamos eso con Separadores Compactados.
Luego nos saltamos los primeros 7 caracteres que son 'doIt ^'

Finalmente, una variante de 105 caracteres que usa stdin, solo interpreta esta oración desde la línea de comandos, solo para sentirte más convencional:

Pharo -headless Pharo-2.0.image eval "FileStream stdin nextLine = (thisContext method decompileString withSeparatorsCompacted allButFirst: 7)"

4

flex - 312 caracteres

Q \"
N \n
S " "
B \\
P "Q{S}{B}{Q}{N}N{S}{B}n{N}S{S}{Q}{S}{Q}{N}B{S}{B}{B}{N}P{S}{Q}{P}{Q}{N}M{S}{Q}{M}{Q}{N}%%{N}{P}{N}{M}{N} putchar('1');"
M "(.|{N})* putchar('0');"
%%
Q{S}{B}{Q}{N}N{S}{B}n{N}S{S}{Q}{S}{Q}{N}B{S}{B}{B}{N}P{S}{Q}{P}{Q}{N}M{S}{Q}{M}{Q}{N}%%{N}{P}{N}{M}{N} putchar('1');
(.|{N})* putchar('0');

Probablemente se puede acortar, pero funciona con entrada de varias líneas (necesario ya que el código fuente es de varias líneas) e incluso para entradas que contienen el programa como una subcadena. Parece que muchas de las respuestas hasta ahora fallan en una o ambas.

Compilar comando: flex id.l && gcc -lfl lex.yy.c


3

D (133 caracteres)

enum c=q{import std.stdio;import std.algorithm;void main(){auto i=readln();writeln(equal("auto c=q{"~c~"};mixin(c);",i));}};mixin(c);

3

JavaScript (V8), 35

function i(){alert(prompt()==i+[])}

llame i()y le pedirá entrada


El +[]debería ser opcional ya que JS lo auto-
tecleará


3

Python 2, 47 bytes

_='_=%r;print _%%_==input()';print _%_==input()

Una quine simple con el cheque agregado.


Esto no funciona printes una función es Python 3. Tendría que hacerlo print(_%%_==input())';print(_%_==input())o cambiarlo a Python 2.
Mego

3

CJam , 12 bytes

{s"_~"+q=}_~

Pruébalo en línea!

Explicación

Esto solo usa el marco estándar de CJam quine.

{s"_~"+q=}    e# Push this block (function literal).
          _~  e# Copy and run it.

Lo que hace el bloque:

 s            e# Stringify the top element (this block itself).
  "_~"+       e# Append "_~". Now the source code is on the stack.
       q      e# Read the input.
        =     e# Check if it equals the source code.

Esta es exactamente la solución que tenía ._.
Esolanging Fruit

2

Tcl, 111 caracteres

set c {set c {$c};puts [expr {[read stdin] eq [subst -noc \$c]}]};puts [expr {[read stdin] eq [subst -noc $c]}]

2

Perl, 52 char

$_='$/=$\;$_="\$_=\47$_\47;eval";print<>eq$_|0';eval

2

Python, 187 bytes

import sys;code="import sys;code=!X!;print(sys.stdin.read()==code.replace(chr(33),chr(34)).replace(!X!,code,1))";print(sys.stdin.read()==code.replace(chr(33),chr(34)).replace("X",code,1))

Cuidado de no agregar nueva línea al final. Alguien con un mejor Python-fu podría acortarlo.


2
Puedes usar C=chrpara soltar varios bytes. Además, acorte el nombre de la variable code.
Zach Gates

2
Como nadie lo dijo durante más de un año, ¡Bienvenido a PPCG!
Erik the Outgolfer

2

Casco , 11 bytes

=hS+s"=hS+s

Pruébalo en línea!

Explicación

La explicación se utiliza ¨para delimitar cadenas (para evitar escapes ilegibles):

     "=hS+s  -- string literal: ¨=hS+s¨
  S+         -- join itself with
    s        -- | itself "showed": ¨"=hS+s"¨
             -- : ¨=hS+s"=hS+s"¨
 h           -- init: ¨=hS+s"=hS+s¨
=            -- is the input equal?

Al eliminar la función =, puede verificar que de hecho solo coincida con la fuente misma.


2

> <> , 24 bytes

'1rd3*i={*}50l3-?.~i)*n;

Pruébalo en línea!

Ajustar literal de cadena seguido de verificar si la entrada es idéntica a la pila, con una comprobación final de que no hay más entrada.


2

Jalea , 10 bytes

“Ṿ;$⁼”Ṿ;$⁼

Pruébalo en línea!

“Ṿ;$⁼”Ṿ;$⁼
“Ṿ;$⁼”      String literal: 'Ṿ;$⁼'
        $   Next two links act on the string literal
      Ṿ     Uneval: '“Ṿ;$⁼”'
       ;    Append string: '“Ṿ;$⁼”Ṿ;$⁼' (source code)
         ⁼  Is the string above equal to the input?

2

05AB1E , 15 bytes

0"D34çýQ"D34çýQ

Modifica la predeterminada 0"D34çý"D34çýagregando Q(verifique la igualdad con la entrada implícita)

Pruébalo en línea.

Explicación:

0                # Push 0 to the stack
                 #  STACK: [0]
 "D34çýQ"        # Push the string 'D34çýQ' to the stack
                 #  STACK: [0, 'D34çýIå']
         D       # Duplicate this string
                 #  STACK: [0, 'D34çýIå', 'D34çýIå']
          34ç    # Push '"' to the stack
                 #  STACK: [0, 'D34çýIå', 'D34çýIå', '"']
             ý   # Join the stack by this '"' delimiter
                 #  STACK: ['0"D34çýIå"D34çýIå']
              Q  # Check if it's equal to the (implicit) input
                 # (and output the top of the stack implicitly as result)

Genial alternativa de 15 bytes proporcionada por @Grimy :

187745012D27BJQ

Pruébalo en línea.

Explicación:

187745012        # Push integer 187745012 
                 #  STACK: [187745012]
         D       # Duplicate it
                 #  STACK: [187745012, 187745012]
          27     # Push integer 27
                 #  STACK: [187745012, 187745012, 27]
            B    # Convert 187745012 to base-27
                 #  STACK: [187745012, "D27BJQ"]
             J   # Join the values on the stack together
                 #  STACK: ["187745012D27BJQ"]
              Q  # Check if it's equal to the (implicit) input
                 # (and output the top of the stack implicitly as result)

3
187745012D27BJQEs un empate.
Grimmy

1

C - 186 176 caracteres

Un trazador de líneas:

 *a="*a=%c%s%c,b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}",b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}

Con espacios en blanco (tenga en cuenta que esto rompe el programa):

*a="*a=%c%s%c,b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}",b[999],c[999];
main() {
  sprintf(b,a,34,a,34);
  gets(c);
  putchar(strcmp(b,c)?'0':'1');
}



1

q, 8 bytes

{x~.z.s}

Devuelve un valor booleano en la entrada que coincide con los .zs autorreferenciales


1

Rúnico , 11 bytes

"3X4+kSqi=@

Pruébalo en línea!

TIO se actualizó y ya no hay un problema al leer la entrada (y ya no requiere un espacio en blanco al final).

Explicación

>                 Implicit entry
 "                Begin reading as string
  3X4+kSqi=@      Pushed to the stack as a string, loop around
 "                End reading as string
  3X4+            Push 3*10 and 4 to the stack, add them together
      k           Convert to character (")
       S          Swap the top two items on the stack
        q         Concatenate. This leaves only "3X4+kSqi=@ on the stack
         i        Read input
          =       Compare using .Equals, push 1 if equal, else 0
           @      Print and terminate

La solución de JoKing:

"'<~qi=@|

Explicación

  <              Entry
 '               Read character (loop around)
"                Push "
         |       Mirror
"                Begin reading string (loop around)
 '<~ri=@|        Push the string '<~qi=@| (loop around)
"                End reading string
 '<~             Push the character < and then discard it
    q            Concatenate, stack contains only "'<~qi=@|
      i          Read input
       =         Compare
        @        Print and terminate


@JoKing Muy inteligente.
Draco18s

En realidad, 9 bytes evitan lo reterno
Jo King

@JoKing Probablemente debería haber podido llegar a eso (de la solución de 10 bytes) yo mismo, pero todavía no he tenido mi cawfee . Ayer ya me había dado cuenta de que tener el "de la izquierda es el único lugar al que realmente puede ir, porque tenerlo en otro lugar complica las cosas. (Pero justo ahora tuve que ejecutarlo en mi depurador para ver qué estaba haciendo ...)
Draco18s

1

R , 54 bytes

f=function(s)s==paste0("f=function(s)s==", body(f)[3])

Pruébalo en línea!

bodyobtiene el cuerpo de la función (dividiéndola un poco, así que eso body(f)[3]es todo desde paste0adelante) Curiosamente, bodyreformatea el código, agrega espacios después de las comas, etc. Por lo tanto, este es un caso raro de una respuesta de R golf con un espacio después de una coma.

Esto funciona porque body(f)es un objeto de tipo language, y existe un as.charactermétodo para este tipo. Por otro lado, fy args(f)son de tipo closure, y no se pueden convertir a tipo de caracteres por lo que puedo decir. Por favor, no me pregunten para qué es el tipo de idioma ...


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.