Écrire le programme d'auto-identification le plus court (une variante de quine)

57

Écrivez un programme qui générera une sortie "vraie" si et si l'entrée correspond au code source du programme et qui génère une sortie "fausse" si et si l'entrée ne correspond pas au code source du programme.

Ce problème peut être décrit comme étant lié aux quines, car le programme doit pouvoir calculer son propre code source dans le processus.

C'est le code golf: les règles standard s'appliquent. Votre programme ne doit pas accéder à des fichiers spéciaux, tels que le fichier de son propre code source.

Edit: Si vous le souhaitez, true / false peut être remplacé par True / False ou 1/0.

Exemple

Si le code source de votre programme est bhiofvewoibh46948732));:/)4, alors voici ce que votre programme doit faire:

Entrée (Stdin)

bhiofvewoibh46948732));:/)4

Sortie (Stdout)

true

Contribution

(Anything other than your source code)

Sortie

false
PhiNotPi
la source
7
La sortie true/ falseest-elle une exigence forte ou les variations ( True/ False, 1/ 0) sont-elles également acceptables?
Cristian Lupascu
Est-ce un problème si le programme génère un peu plus que vrai / faux (s'il continue à être sans ambiguïté et se termine par vrai / faux)?
Denys Séguret le
1
Connexes: Interpréter votre langue, mais pas vous
Ilmari Karonen
5
Donc, vous voulez dire un programme narcissique?
PyRulez

Réponses:

33

JavaScript: 26

function f(s){return s==f}

Je ne sais pas si un fichier JavaScript est réellement qualifié de "programme".

Denys Séguret
la source
7
+1 Cela fonctionne car tous les objets ont une .toString()méthode en JavaScript .
Andrew Larsson
Cela peut être raccourci en utilisant une fonction flèchef=s=>s=='f='+f
Jonathan
2
@ Jonathan oui. Mais en 2013, cela ne pouvait pas ...
Denys Séguret
19

JavaScript ES6, 9 caractères

C’est la seule façon (golfeuse) de le faire en JS. ES6 rend juste moins super caractères

Exécutez ceci dans la dernière console Web de Firefox:

f=x=>f==x

Exemple d'utilisation:

f("check") // returns false
f("x=>f==x") // returns true
Optimiseur
la source
1
@phinotpi - Mon entrée est-elle toujours éligible pour être choisie comme réponse?
Optimiseur
6
On pourrait toutefois soutenir que la source dans cette affaire est une source f=x=>f==xet non x=>f==x, alors que la version de Denys Séguret vérifie effectivement toute la source.
Hankrecords
@Hankrecords Laissez JavaScript décider de cela. f=x=>f==x function f() f.toSource() "x=>f==x"(En gros, évaluez le code dans la console, puis f.toSource()dans un navigateur prenant en charge cette méthode.
Optimiseur
Les fonctions anonymes ne sont pas autorisées (raccourcissez votre code en x=>f==x) EDIT: tant pis, f est référencé à l'intérieur de la fonction
MilkyWay90
9

Haskell, 72 caractères

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

Remarque: il n'y a pas de caractère de fin de ligne à la fin du script.

$ runhaskell Self.hs < Self.hs
True
hammar
la source
8

GolfScript, 11 caractères

{`".~"+=}.~

Sans le =, ce code serait un code qui génère son propre code source sous forme de chaîne. Le =fait qu'il compare cette chaîne à son entrée et de sortie 1si elles correspondent et 0si elles ne le font pas. Notez que la comparaison est exacte - en particulier, un retour à la fin à la fin de l'entrée entraînera l'échec.

Explication:

  • { } est un littéral de bloc de code dans GolfScript;
  • .duplique ce bloc de code et ~exécute la deuxième copie (en laissant la première sur la pile);
  • `chaîne le bloc de code et ".~"+ y ajoute .~;
  • Enfin, =compare la chaîne résultante à l'entrée (qui est poussée sur la pile en tant que chaîne par l'interpréteur GolfScript avant le démarrage du programme) et renvoie 1si elles correspondent et 0si elles ne correspondent pas.
Ilmari Karonen
la source
7

Perl, Infinity 41 38 Caractères

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

Mise à jour: le programme ne se termine plus par une nouvelle ligne, ce qui signifie qu'il fonctionnera correctement sur des fichiers multilignes. Vous devez entrer une entrée de STDIN sans appuyer sur enter. Sous Windows, je ne pouvais le faire qu'en lisant un fichier.

Solution originale:

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

la source
1
Bien fait! . . .
mob
Échec pour un fichier commençant par le code, par exemple(cat id.pl; echo foo)|perl id.pl
Geoff Reedy
@ GeoffReedy, merci; le programme ne gérait pas la saisie multiligne auparavant. C'est corrigé maintenant.
Bon sang, ce code est-il un bowling?
Matthew Roh
7

> <> , 68 octets

Les poissons adorent manger du caca de poisson. Nous savons maintenant qu'ils peuvent distinguer les leurs de ceux de leurs amis.

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

Vous pouvez l' essayer en ligne !

Aaron
la source
1
Cela produit également 1un préfixe du code
Jo King
@JoKing était pire que les préfixes du script, il acceptait aussi les lignes tronquées! Je l'ai corrigé, mais je suis déçu que ce ne soit pas aussi générique que je le voulais, je devais vérifier la cellule atteinte à la fin du script pour m'assurer que tout le code était apparié. Cela peut certainement être amélioré, mais je ne suis pas sûr que je vais m'en préoccuper.
Aaron
6

Python 2, 55

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

Testé:

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

(anything else) -> False

flornquake
la source
3
Échec sur tous les fichiers commençant par la première ligne a='a=%r;print a%%a==raw_input()';print a%a==raw_input().
Boothby
True, la saisie multiligne n’est pas prise en charge.
Flornquake
Une solution triviale serait de remplacer raw_input()par __import__('sys').stdin.read().
Feersum
Je suis confus par le libellé du défi (parce que je ne suis pas bon avec la grammaire anglaise). Est-ce permis? print raw_input()==open(__file__).read()? Ce n'est que 40 octets, utilise votre raw_input()approche, mais lit son code.
Simon le
1
@Simon Cela n'est pas autorisé, c'est l'une des échappatoires standard pour des défis comme celui-ci. Et oui, Your program must not access any special files, such as the file of its own source code.
voici
6

JavaScript ES6, 16 14 octets

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

Moins deux octets grâce à Neil.

31 octets si nous devons prendre une entrée via invite.

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

38 octets si nous devons sortir par alerte.

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

C’est la bonne façon de procéder car la réponse d’Optimizer n’accepte pas l’ensemble du code source.

Conor O'Brien
la source
1
Nice, bien que je voudrais juste écrire '$='+$.
Neil
Oh c'est vrai. @Neil
Conor O'Brien
1
Je suis sûr que vous avez besoin de la fin ;$()car l'appel de fonction fait partie de la quine. Cela signifie également que vous devrez basculer sur promptpour prendre en compte les entrées.
Mama Fun Roll
1
Ce n'est pas le problème. L'appel de fonction est nécessaire car il fait partie de la quine. Permettre à l'utilisateur de l'appeler en tant que fonction ruinerait le quine.
Mama Fun Roll
1
essayer$=_=>prompt()==`$=${$};$()`;$()
Mama Fun Roll
5

Node.js: 54

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

Vous le testez en l'enregistrant dans un fichier f.js(le nom exact n'a pas d'importance) et en utilisant

node f.js "test"

(qui renvoie faux) ou

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

(qui produit true)

J'ai aussi créé une version différente basée sur eval:

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

Il est maintenant à 72 caractères, je vais essayer de réduire cela quand j'ai le temps.

Denys Séguret
la source
1
@ dan1111 Pourquoi? Il n'accède à aucun fichier. Je pointais juste comment lancer le programme à des personnes non habituées à node.js. Il ne lit pas le fichier.
Denys Séguret
1
Toutes les solutions Javascript tirent parti du fait que vous pouvez accéder à votre propre code source dans JS. Cela n’est peut-être pas techniquement "accéder au fichier de son propre code source", mais cela produit exactement la même chose. Je suppose que votre réponse est légale, car la question ne l’interdit pas expressément.
Eh bien, vous accédez à la source d'une fonction (seul le corps pour être précis) qui fait partie du programme. C'est comme utiliser mixin () dans D. Mais je ne pense pas que les deux autres réponses de JS, y compris une de moi, soient réellement qualifiées de "programmes".
Denys Séguret le
@dystroy mixin en D ressemble plus à eval qu'à lecture de source
freaket freak,
@ Ratchetfreak Oui, vous avez raison. Mais je pense que votre programme utilise une sorte de chaîne de la valeur enum, non? Et tout code utilisant eval / mixin est à peu près le même truc que d’utiliser la source de la fonction.
Denys Séguret le
5

Smalltalk (dialecte Pharo 2.0)

Implémentez cette méthode 41 caractères dans String (mise en forme laide pour code-golf):

isItMe^self=thisContext method sourceCode

Puis évaluez ceci dans un espace de travail (printIt la manière traditionnelle de Smalltalk).
L'entrée n'est pas lue à partir de stdin, c'est simplement une chaîne à laquelle nous envoyons le message (quoi d'autre un programme pourrait être en Smalltalk?):

'isItMe^self=thisContext method sourceCode' isItMe.

Mais nous trichons, sourceCode lit un fichier source ...
Voici une variante à 51 caractères qui ne le fait pas:

isItMe
    ^ self = thisContext method decompileString

Et tester avec:

'isItMe
    ^ self = thisContext method decompileString' isItMe

Si une chaîne dans un espace de travail n'est pas considérée comme une entrée valide, voyons comment utiliser certaines boîtes de dialogue en 116 caractères. Évaluez
simplement cette phrase:

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

Comme le format de décompilation comprend CR et TAB, nous le modifions avecSeparatorsCompressed.
Ensuite, nous sautons les 7 premiers caractères sont 'doIt ^'

Enfin, une variante à 105 caractères utilisant stdin, interprétez cette phrase à partir de la ligne de commande, pour vous sentir plus courant:

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

flex - 312 caractères

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');

Peut probablement être raccourci, mais cela fonctionne avec une entrée multiligne (nécessaire car le code source est composé de plusieurs lignes) et même avec des entrées contenant le programme en tant que sous-chaîne. Il semble que beaucoup de réponses à ce jour échouent sur l’un ou les deux.

Commande de compilation: flex id.l && gcc -lfl lex.yy.c

Geoff Reedy
la source
3

D (133 caractères)

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);
monstre à cliquet
la source
3

JavaScript (V8), 35

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

appel i()et il vous demandera d'entrer

Griffon
la source
Le +[]devrait être facultative comme JS volonté automatique de type moulé , elle
Downgoat
3

GolfScript - 26

":@;[34]@+2*=":@;[34]@+2*=

Inspiré de http://esolangs.org/wiki/GolfScript#Examples

Une autre version:

"[34].@@;+2*="[34].@@;+2*=

Dommage que ce \soit à la fois un échange et une évasion ...

Aditsu
la source
3

Python 2, 47 octets

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

Un quine simple avec le chèque ajouté.

Rɪᴋᴇʀ
la source
Ça ne marche pas. printest une fonction est Python 3. Vous devez le faire print(_%%_==input())';print(_%_==input())ou le changer en Python 2.
Mego
3

CJam , 12 octets

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

Essayez-le en ligne!

Explication

Ceci utilise simplement le framework standard CJam Quine.

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

Que fait le bloc:

 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.
Chat d'affaires
la source
C’est exactement la solution que j’avais ._.
Esolanging Fruit
2

Tcl, 111 caractères

set c {set c {$c};puts [expr {[read stdin] eq [subst -noc \$c]}]};puts [expr {[read stdin] eq [subst -noc $c]}]
Johannes Kuhn
la source
2

Perl, 52 caractères

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

Python, 187 octets

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))

Attention à ne pas ajouter de nouvelle ligne à la fin. Quelqu'un avec un meilleur Python-Fu pourrait peut-être le raccourcir.

Emilio
la source
2
Vous pouvez utiliser C=chrpour supprimer plusieurs octets. Réduisez également le nom de la variable code.
Zach Gates
2
Puisque personne ne le dit depuis plus d'un an, bienvenue à PPCG!
Erik l'Outgolfer
2

Coque , 11 octets

=hS+s"=hS+s

Essayez-le en ligne!

Explication

L'explication utilise ¨pour délimiter les chaînes (pour éviter les échappements illisibles):

     "=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?

En supprimant la fonction, =vous pouvez vérifier qu’elle ne correspondra en réalité qu’à la source elle-même.

ბიმო
la source
2

> <> , 24 octets

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

Essayez-le en ligne!

Retour à la ligne d'un littéral de chaîne suivi de la vérification de la correspondance de l'entrée avec la pile, puis d'une vérification de l'absence de toute autre entrée.

Jo King
la source
2

Gelée , 10 octets

“Ṿ;$⁼”Ṿ;$⁼

Essayez-le en ligne!

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

05AB1E , 15 octets

0"D34çýQ"D34çýQ

Modifie le 0"D34çý"D34çý par défaut en ajoutant Q(vérifier l’égalité avec l’entrée implicite)

Essayez-le en ligne.

Explication:

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)

Variante cool de 15 octets fournie par @Grimy :

187745012D27BJQ

Essayez-le en ligne.

Explication:

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)
Kevin Cruijssen
la source
3
187745012D27BJQest une cravate.
Grimmy
1

C - 186 176 caractères

Bon mot:

 *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');}

Avec des espaces (notez que cela casse le programme):

*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');
}
Josh
la source
1

q, 8 octets

{x~.z.s}

Renvoie une valeur booléenne correspondant au repère auto-référentiel .zs

Thaufeki
la source
1

Runique , 11 octets

"3X4+kSqi=@

Essayez-le en ligne!

TIO a été mis à jour et il n'y a plus de problème de lecture d'entrée (et ne nécessite plus d'espaces de fin).

Explication

>                 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 solution de JoKing:

"'<~qi=@|

Explication

  <              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
Draco18s
la source
1
10 octets
Jo King le
@JoKing Très intelligent.
Draco18s
En fait, 9 octets évitent l’effet rinverse
Jo King le
@JoKing J'aurais probablement dû pouvoir y arriver moi-même (à partir de la solution à 10 octets), mais je n'ai pas encore eu mon cawfee . Hier, j'avais déjà compris qu'avoir la "gauche était le seul endroit où il pouvait vraiment aller, parce que le faire ailleurs compliquait les choses. (Mais tout à l'heure, je devais l'exécuter dans mon débogueur pour voir ce qu'il était en train de faire ...)
Draco18s
1

R , 54 octets

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

Essayez-le en ligne!

bodyrécupère le corps de la fonction (en le divisant un peu, c'est body(f)[3]donc tout à paste0partir de maintenant). Fait intéressant, bodyreformate le code, ajoute des espaces après des virgules, etc. Il s’agit donc d’un cas rare de réponse de golf R avec un espace après une virgule.

Cela fonctionne car il body(f)s'agit d'un objet de type languageet il existe une as.characterméthode pour ce type. D'autre part, fet args(f)sont de type closure, et ne peuvent pas être convertis en type de caractère pour autant que je sache. S'il vous plaît ne me demandez pas quel est le type de langue…

Robin Ryder
la source