Scrivi il programma di autoidentificazione più breve (una variante di quine)


57

Scrivere un programma che genererà un output "vero" se l'ingresso corrisponde al codice sorgente del programma e che genera un output "falso" se l'ingresso non corrisponde al codice sorgente del programma.

Questo problema può essere descritto come correlato a quines, in quanto il programma deve essere in grado di calcolare in qualche modo il proprio codice sorgente nel processo.

Questo è il golf del codice: si applicano le regole standard. Il tuo programma non deve accedere ad alcun file speciale, come ad esempio il file del proprio codice sorgente.

Modifica: se lo desideri, true / false può essere sostituito con True / False o 1/0.

Esempio

Se il codice sorgente del tuo programma è bhiofvewoibh46948732));:/)4, allora ecco cosa deve fare il tuo programma:

Ingresso (Stdin)

bhiofvewoibh46948732));:/)4

Uscita (Stdout)

true

Ingresso

(Anything other than your source code)

Produzione

false

7
L' output true/ falseè un requisito forte o sono accettabili anche le variazioni ( True/ False, 1/ 0)?
Cristian Lupascu,

È un problema se il programma emette un po 'più di vero / falso (se continua a non essere ambiguo e termina con vero / falso)?
Denys Séguret,


5
Quindi intendi un programma narcisista?
PyRulez,

Risposte:



19

JavaScript ES6, 9 caratteri

Questo è l'unico modo (da golf) di farlo in JS. ES6 richiede solo meno caratteri

Esegui questo nella più recente console Web di Firefox:

f=x=>f==x

Esempio di utilizzo:

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

1
@phinotpi - La mia iscrizione è ancora idonea a essere selezionata come risposta?
Ottimizzatore

6
Si potrebbe sostenere che la fonte in questo caso è f=x=>f==xe non lo è x=>f==x, mentre la versione di Denys Séguret controlla davvero l'intera fonte.
Hankrecords,

@Hankrecords Lascia che JavaScript lo decida. f=x=>f==x function f() f.toSource() "x=>f==x"(fondamentalmente valuta il codice nella console e quindi valuta f.toSource()in un browser che supporta quel metodo.
Ottimizzatore

Non sono ammesse funzioni anonime (abbrevia il codice in x=>f==x) MODIFICA: non importa, f fa riferimento all'interno della funzione
MilkyWay90

9

Haskell, 72 caratteri

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

Nota: non esiste un carattere di fine riga alla fine dello script.

$ runhaskell Self.hs < Self.hs
True

8

GolfScript, 11 caratteri

{`".~"+=}.~

Senza il =, questo codice sarebbe un quine che genera il proprio codice sorgente come stringa. Lo =fa confrontare questa stringa con il suo input e output 1se corrispondono e 0se non lo fanno. Si noti che il confronto è esatto - in particolare, una nuova riga finale alla fine dell'input provocherà il fallimento.

Spiegazione:

  • { } è un blocco di codice letterale in GolfScript;
  • .duplica questo blocco di codice ed ~esegue la seconda copia (lasciando la prima in pila);
  • `stringa il blocco di codice e ".~"+ lo accoda .~;
  • infine, =confronta la stringa risultante con l'input (che viene inserito nello stack come stringa dall'interprete GolfScript prima dell'avvio del programma) e restituisce 1se corrispondono e 0se non lo fanno.

7

Perl, Infinity 41 38 personaggi

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

Aggiornamento: il programma non termina più con una nuova riga, il che significa che funzionerà correttamente su file multilinea. Devi inserire input da STDIN senza premere invio. Su Windows sono stato in grado di farlo solo leggendo da un file.

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

1
Ben fatto! . . .
mob

Non riesce a trovare un file che inizia con il codice, ad es(cat id.pl; echo foo)|perl id.pl
Geoff Reedy del

@GeoffReedy, grazie; il programma non ha gestito prima l'input multi-linea. Ora è corretto.

Accidenti, questo codice è bowling?
Matthew Roh,

7

> <> , 68 byte

I pesci adorano mangiare la cacca di pesce. Ora sappiamo che possono distinguere i loro dai loro amici.

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

Puoi provarlo online !


1
Questo produce anche 1qualsiasi prefisso del codice
Jo King,

@JoKing è stato peggio dei semplici prefissi dello script, ha accettato anche le linee troncate! L'ho risolto, ma sono deluso che non sia generico come volevo, ho dovuto controllare la cella raggiunta alla fine dello script per assicurarmi che l'intero codice fosse abbinato. Può certamente essere migliorato, ma non sono sicuro che mi darò fastidio.
Aaron,

6

Python 2, 55

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

Provato:

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

(anything else) -> False


3
Non riesce su qualsiasi file che inizia con la prima riga uguale a a='a=%r;print a%%a==raw_input()';print a%a==raw_input().
stand,

Il vero input multi-linea non è supportato.
terremoto del

Una banale soluzione sarebbe sostituirla raw_input()con __import__('sys').stdin.read().
feersum

Sono confuso dal testo della sfida (perché non sono bravo con la grammatica inglese). È permesso? print raw_input()==open(__file__).read()? Sono solo 40 byte, usa il tuo raw_input()approccio, ma legge il suo codice.
Simon,

1
@Simon Non è permesso, è una delle scappatoie standard per sfide come questa. E sì, questo è ciò che significaYour program must not access any special files, such as the file of its own source code.
PunPun1000,

6

JavaScript ES6, 16 14 byte

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

Meno due byte grazie a Neil.

31 byte se dobbiamo accettare input tramite prompt.

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

38 byte se dobbiamo emettere tramite avviso.

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

Questo è il modo corretto di farlo, poiché la risposta di Optimizer non accetta l'intero codice sorgente.


1
Bello, anche se vorrei solo scrivere '$='+$.
Neil,

Oh vero @Neil
Conor O'Brien,

1
Sono abbastanza sicuro che hai bisogno del finale ;$()perché la chiamata di funzione fa parte del quine. Questo significa anche che dovrai passare promptall'account per l'input.
Mama Fun Roll

1
Non è questo il problema. La chiamata di funzione è necessaria perché fa parte del quine. Consentire all'utente di chiamarlo come funzione rovinerebbe il quine.
Mama Fun Roll

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

5

Node.js: 54

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

Lo provi salvandolo in un file f.js(il nome esatto non ha importanza) e usando

node f.js "test"

(che genera false) o

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

(che genera true)

Ho anche realizzato una versione diversa basata su eval:

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

Ora è a 72 caratteri, cercherò di accorciarlo quando avrò tempo.


1
@ dan1111 Perché? Non accede a nessun file. Stavo solo indicando come avviare il programma a persone non abituate a node.js. Non legge il file.
Denys Séguret,

1
Tutte le soluzioni Javascript sfruttano il fatto che è possibile accedere al proprio codice sorgente in JS. Potrebbe non essere tecnicamente "accedere al file del proprio codice sorgente", ma realizza esattamente la stessa cosa. Suppongo che la tua risposta sia legale, tuttavia, poiché la domanda non lo ha proibito espressamente.

Bene, accedi alla fonte di una funzione (solo il corpo per essere precisi) che fa parte del programma. È come usare mixin () in D. Ma non penso che le altre due risposte di JS, inclusa una mia, si qualifichino davvero come "programmi".
Denys Séguret,

@dystroy in realtà mixin in D è più come usare eval che leggere source
maniaco del cricchetto

@ratchetfreak sì, hai ragione. Ma penso che il tuo programma usi una specie di stringa del valore enum, giusto? E qualsiasi codice che usa eval / mixin è più o meno lo stesso che usare l'origine della funzione.
Denys Séguret,

5

Smalltalk (dialetto Pharo 2.0)

Implementa questo metodo 41 caratteri in String (brutta formattazione per code-golf):

isItMe^self=thisContext method sourceCode

Quindi valuta questo in uno spazio di lavoro (printIt nel tradizionale modo Smalltalk)
L'input non viene letto da stdin, è solo una stringa a cui inviamo il messaggio (cos'altro potrebbe essere un programma in Smalltalk?):

'isItMe^self=thisContext method sourceCode' isItMe.

Ma stiamo barando, sourceCode legge alcuni file sorgente ...
Ecco una variante con 51 caratteri che non:

isItMe
    ^ self = thisContext method decompileString

E prova con:

'isItMe
    ^ self = thisContext method decompileString' isItMe

Se una stringa in un'area di lavoro non è considerata un input valido, allora vediamo come utilizzare alcune finestre di dialogo in 116 caratteri.
Valuta solo questa frase:

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

Poiché il formato di decompilazione include CR e TAB, lo cambiamo con SeparatorsCompacted.
Quindi saltiamo i primi 7 caratteri sono 'doIt ^'

Finalmente una variante di 105 caratteri usando stdin, basta interpretare questa frase dalla riga di comando, solo per sentirsi più mainstream:

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

4

flex - 312 caratteri

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

Probabilmente può essere abbreviato, ma funziona con input multi-linea (necessario poiché il codice sorgente è più righe) e anche per input che contengono il programma come sottostringa. Sembra che molte delle risposte finora falliscano su una o entrambe.

Comando di compilazione: flex id.l && gcc -lfl lex.yy.c


3

D (133 caratteri)

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+[])}

chiama i()e richiederà l'input


Il +[]dovrebbe essere facoltativo come JS volontà auto-tipo-lanciarlo
Downgoat


3

Python 2, 47 byte

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

Un semplice quine con il controllo aggiunto.


Questo non funziona printè una funzione è Python 3. Dovresti farlo print(_%%_==input())';print(_%_==input())o cambiarlo in Python 2.
Mego

3

CJam , 12 byte

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

Provalo online!

Spiegazione

Questo utilizza solo il framework standard CJam quine.

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

Cosa fa il blocco:

 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.

Questa è esattamente la soluzione che ho avuto ._.
Esolanging Fruit il

2

Tcl, 111 caratteri

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

2

Perl, 52 caratteri

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

2

Python, 187 byte

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

Attento a non aggiungere newline alla fine. Qualcuno con Python-fu migliore potrebbe essere in grado di accorciarlo.


2
È possibile utilizzare C=chrper eliminare diversi byte. Inoltre, abbreviare il nome della variabile code.
Zach Gates,

2
Dal momento che nessuno lo ha detto per oltre un anno, benvenuto in PPCG!
Erik the Outgolfer,

2

Buccia , 11 byte

=hS+s"=hS+s

Provalo online!

Spiegazione

La spiegazione utilizza ¨per delimitare le stringhe (per evitare l'escaping illeggibile):

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

Rimuovendo la funzione =è possibile verificare che corrisponderà effettivamente solo alla fonte stessa.


2

> <> , 24 byte

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

Provalo online!

Stringa di avvolgimento letterale seguita da verifica se l'input è identico allo stack, con un controllo finale che non ci sono più input.


2

Gelatina , 10 byte

“Ṿ;$⁼”Ṿ;$⁼

Provalo online!

“Ṿ;$⁼”Ṿ;$⁼
“Ṿ;$⁼”      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 byte

0"D34çýQ"D34çýQ

Modifica il predefinito 0"D34çý"D34çýaggiungendo Q(controlla l'uguaglianza con l'input implicito)

Provalo online.

Spiegazione:

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)

Fantastica alternativa a 15 byte fornita da @Grimy :

187745012D27BJQ

Provalo online.

Spiegazione:

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
187745012D27BJQè un pareggio.
Grimmy,

1

C - 186 176 caratteri

Una fodera:

 *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 spazi bianchi (nota che questo interrompe il programma):

*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 byte

{x~.z.s}

Restituisce il valore booleano sull'input corrispondente al .zs autoreferenziale


1

Runico , 11 byte

"3X4+kSqi=@

Provalo online!

TIO è stato aggiornato e non c'è più alcun problema a leggere l'input (e non richiede più uno spazio bianco finale).

Spiegazione

>                 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 soluzione di JoKing:

"'<~qi=@|

Spiegazione

  <              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 Molto intelligente.
Draco18s

In realtà, 9 byte evita l' reverse
Jo King,

@JoKing Probabilmente avrei dovuto essere in grado di arrivare a quello (dalla soluzione da 10 byte), ma non ho ancora avuto il mio cawfee . Ieri avevo già capito che avere "a sinistra è l'unico posto dove può davvero andare, perché averlo altrove complica le cose. (Ma proprio ora ho dovuto eseguirlo nel mio debugger per vedere cosa stava facendo ...)
Draco18s

1

R , 54 byte

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

Provalo online!

bodyottiene il corpo della funzione (suddividendolo un po ', in modo che body(f)[3]sia tutto da paste0capo in poi). È interessante notare che bodyriformatta il codice, aggiungendo spazi dopo virgole, ecc. Questo è quindi un raro caso di una risposta R golf con uno spazio dopo una virgola.

Questo funziona perché body(f)è un oggetto di tipo languageed esiste un as.charactermetodo per questo tipo. D'altra parte, fe args(f)sono di tipo closuree non possono essere convertiti in tipo di carattere per quanto ne so. Per favore, non chiedermi quale sia il tipo di lingua per ...


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.