Tulis program pengidentifikasi diri terpendek (varian quine)


57

Tulis program yang akan menghasilkan keluaran "benar" jika input cocok dengan kode sumber program, dan yang menghasilkan output "salah" jika input tidak cocok dengan kode sumber program.

Masalah ini dapat digambarkan sebagai terkait dengan quines, karena program harus dapat entah bagaimana menghitung kode sumbernya sendiri dalam proses.

Ini adalah kode golf: aturan standar berlaku. Program Anda tidak boleh mengakses file khusus apa pun, seperti file kode sumbernya sendiri.

Sunting: Jika Anda memilih, benar / salah dapat diganti dengan Benar / Salah atau 1/0.

Contoh

Jika kode sumber program Anda adalah bhiofvewoibh46948732));:/)4, maka inilah yang harus dilakukan oleh program Anda:

Input (Stdin)

bhiofvewoibh46948732));:/)4

Output (Stdout)

true

Memasukkan

(Anything other than your source code)

Keluaran

false

7
Apakah true/ falseoutput persyaratan yang kuat, atau apakah variasi ( True/ False, 1/ 0) dapat diterima juga?
Cristian Lupascu

Apakah ini masalah jika program mengeluarkan sedikit lebih dari true / false (jika tetap tidak ambigu dan diakhiri dengan true / false)?
Denys Séguret


5
Jadi maksud Anda program narsisis?
PyRulez

Jawaban:



19

JavaScript ES6, 9 karakter

Ini adalah satu-satunya cara (golf) untuk melakukannya di JS. ES6 hanya membuatnya mengambil karakter yang lebih sedikit

Jalankan ini di Konsol Web Firefox terbaru:

f=x=>f==x

Contoh penggunaan:

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

1
@phinotpi - Apakah entri saya masih layak dipilih sebagai jawaban?
Pengoptimal

6
Dapat dikatakan bahwa sumber dalam kasus ini adalah f=x=>f==xdan tidak x=>f==x, sedangkan versi Denys Séguret memang memeriksa seluruh sumber.
Hankrecords

@Hankrecords Biarkan JavaScript yang memutuskan itu. f=x=>f==x function f() f.toSource() "x=>f==x"(pada dasarnya mengevaluasi kode di konsol dan kemudian mengevaluasi f.toSource()di browser yang mendukung metode itu.
Pengoptimal

Tidak diperbolehkan fungsi anonim (persingkat kode Anda menjadi x=>f==x) EDIT: nevermind, f dirujuk di dalam fungsi
MilkyWay90

9

Haskell, 72 karakter

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

Catatan: tidak ada karakter end-of-line di akhir skrip.

$ runhaskell Self.hs < Self.hs
True

8

GolfScript, 11 karakter

{`".~"+=}.~

Tanpa =, kode ini akan menjadi quine yang menghasilkan kode sumbernya sendiri sebagai string. Itu =membuatnya membandingkan string ini dengan input dan outputnya 1jika cocok dan 0jika tidak. Perhatikan bahwa perbandingannya tepat - khususnya, baris baru yang tertinggal di akhir input akan menyebabkannya gagal.

Penjelasan:

  • { } adalah kode blok literal dalam GolfScript;
  • .menduplikasi blok kode ini, dan ~mengeksekusi salinan kedua (meninggalkan yang pertama di tumpukan);
  • `menguatkan blok kode, dan ".~"+ menambahkannya .~;
  • akhirnya, =bandingkan string yang dihasilkan dengan input (yang didorong pada stack sebagai string oleh penerjemah GolfScript sebelum program dimulai) dan kembali 1jika cocok dan 0jika tidak.

7

Perl, Infinity 41 38 Karakter

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

Pembaruan: Program tidak lagi berakhir dengan baris baru, yang berarti akan berfungsi dengan benar pada file multi-line. Anda harus memasukkan input dari STDIN tanpa menekan enter. Di Windows saya hanya bisa melakukan ini dengan membaca dari file.

Solusi asli:

print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(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
Bagus sekali! . . .
mob

Gagal untuk file yang dimulai dengan kode, misalnya(cat id.pl; echo foo)|perl id.pl
Geoff Reedy

@ GeoffReedy, terima kasih; program tidak menangani input multi-line sebelumnya. Itu diperbaiki sekarang.

Sial, apakah kode ini bowling?
Matthew Roh

7

> <> , 68 byte

Ikan suka makan kotoran ikan. Sekarang kita tahu mereka bisa membedakan mereka dari teman mereka.

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

Anda dapat mencobanya secara online !


1
Ini menghasilkan 1awalan kode apa pun juga
Jo King

@JoKing itu lebih buruk daripada awalan skrip, ia juga menerima baris terpotong! Saya sudah memperbaikinya, tetapi saya kecewa itu tidak generik seperti yang saya inginkan, saya harus memeriksa sel yang tercapai di akhir skrip untuk memastikan seluruh kode cocok. Tentu saja bisa diperbaiki, tetapi saya tidak yakin saya akan repot.
Aaron

6

Python 2, 55

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

Diuji:

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

(anything else) -> False


3
Gagal pada file apa pun yang dimulai dengan baris pertama sama dengan a='a=%r;print a%%a==raw_input()';print a%a==raw_input().
stan

Benar, input multi-jalur tidak didukung.
flornquake

Perbaikan sepele akan diganti raw_input()dengan __import__('sys').stdin.read().
feersum

Saya bingung dengan kata-kata tantangan (karena saya tidak pandai tata bahasa Inggris). Apakah ini diizinkan? print raw_input()==open(__file__).read()? Ini hanya 40 byte, menggunakan raw_input()pendekatan Anda , tetapi membaca kodenya.
Simon

1
@Simon Itu tidak diperbolehkan, itu adalah salah satu celah standar untuk tantangan seperti ini. Dan ya, inilah yang dimaksud denganYour program must not access any special files, such as the file of its own source code.
PunPun1000

6

JavaScript ES6, 16 14 byte

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

Minus dua byte terima kasih kepada Neil.

31 byte jika kita harus mengambil input melalui prompt.

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

38 byte jika kita harus mengeluarkan melalui peringatan.

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

Ini adalah cara yang tepat untuk melakukannya, karena jawaban Pengoptimal tidak menerima seluruh kode sumber.


1
Bagus, meskipun saya hanya akan menulis '$='+$.
Neil

Oh benar @Neil
Conor O'Brien

1
Saya cukup yakin Anda memerlukan akhir ;$()karena pemanggilan fungsi adalah bagian dari quine. Ini juga berarti bahwa Anda harus beralih promptke akun untuk input.
Mama Fun Roll

1
Bukan itu masalahnya. Panggilan fungsi diperlukan karena itu adalah bagian dari quine. Mengizinkan pengguna untuk menyebutnya sebagai fungsi akan merusak quine.
Mama Fun Roll

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

5

Node.js: 54

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

Anda mengujinya dengan menyimpannya ke file f.js(nama yang tepat tidak penting) dan menggunakan

node f.js "test"

(yang menghasilkan false) atau

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

(yang menghasilkan true)

Saya juga membuat versi berbeda berdasarkan eval:

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

Sekarang di 72 karakter, saya akan mencoba untuk mempersingkat ketika saya punya waktu.


1
@ dan1111 Kenapa? Itu tidak mengakses file apa pun. Saya hanya menunjukkan cara meluncurkan program kepada orang-orang yang tidak terbiasa dengan node.js. Itu tidak membaca file.
Denys Séguret

1
Semua solusi Javascript memanfaatkan fakta bahwa Anda dapat mengakses kode sumber Anda sendiri di JS. Itu mungkin tidak secara teknis "mengakses file kode sumbernya sendiri", tetapi melakukan hal yang sama persis. Saya kira jawaban Anda sah, karena pertanyaannya tidak secara khusus melarang ini.

Nah, Anda mengakses sumber suatu fungsi (hanya bodi tepatnya) yang merupakan bagian dari program. Itu seperti menggunakan mixin () dalam D. Tapi saya tidak berpikir dua jawaban JS lainnya, termasuk satu dari saya, benar-benar memenuhi syarat sebagai "program".
Denys Séguret

@dystroy sebenarnya mixin dalam D lebih seperti menggunakan eval daripada membaca sumber
ratchet freak

@ scratchetfreak ya, Anda benar. Tapi saya pikir program Anda menggunakan semacam toString dari nilai enum, kan? Dan setiap kode yang menggunakan eval / mixin adalah trik yang sama daripada menggunakan sumber fungsi.
Denys Séguret

5

Smalltalk (dialek Pharo 2.0)

Terapkan metode 41 karakter ini di String (format jelek untuk kode-golf):

isItMe^self=thisContext method sourceCode

Kemudian evaluasi ini di Workspace (printIt cara Smalltalk tradisional)
Input tidak dibaca dari stdin, itu hanya sebuah String yang kami kirim pesan (apa lagi program bisa di Smalltalk?):

'isItMe^self=thisContext method sourceCode' isItMe.

Tapi kami curang, sourceCode membaca beberapa file sumber ...
Berikut ini varian dengan 51 karakter yang tidak:

isItMe
    ^ self = thisContext method decompileString

Dan uji dengan:

'isItMe
    ^ self = thisContext method decompileString' isItMe

Jika sebuah String di dalam Workspace tidak dianggap sebagai input yang valid, maka mari kita lihat bagaimana menggunakan beberapa Kotak Dialog dalam 116 karakter.
Cukup evaluasi kalimat ini:

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

Karena format dekompilasi menyertakan CR dan TAB, kami mengubahnya denganSeparatorsCompacted.
Lalu kita lewati 7 karakter pertama yaitu 'doIt ^'

Akhirnya varian 105 karakter menggunakan stdin, cukup interpretasikan kalimat ini dari baris perintah, hanya untuk merasa lebih umum:

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

4

flex - 312 karakter

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

Mungkin bisa dibuat lebih pendek, tetapi ia bekerja dengan input multi-line (diperlukan karena kode sumber adalah beberapa baris) dan bahkan untuk input yang berisi program sebagai substring. Tampaknya banyak jawaban sejauh ini gagal pada satu atau keduanya.

Kompilasi perintah: flex id.l && gcc -lfl lex.yy.c


3

D (133 karakter)

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

panggilan i()dan itu akan meminta input


The +[]harus opsional sebagai JS akan auto-jenis-cast itu
Downgoat


3

Python 2, 47 byte

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

Quine sederhana dengan cek yang ditambahkan.


Ini tidak bekerja printadalah fungsi adalah Python 3. Anda harus melakukan print(_%%_==input())';print(_%_==input())atau mengubahnya ke Python 2.
Mego

3

CJam , 12 byte

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

Cobalah online!

Penjelasan

Ini hanya menggunakan kerangka quine CJam standar.

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

Apa yang dilakukan oleh blok:

 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.

Inilah solusi yang saya miliki ._.
Buah Esolanging

2

Tcl, 111 karakter

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

Hati-hati untuk tidak menambahkan baris baru di akhir. Seseorang dengan Python-fu yang lebih baik mungkin bisa mempersingkatnya.


2
Anda dapat menggunakan C=chruntuk menjatuhkan beberapa byte. Juga, persingkat nama variabel code.
Zach Gates

2
Karena tidak ada yang mengatakannya selama lebih dari setahun, Selamat datang di PPCG!
Erik the Outgolfer

2

Sekam , 11 byte

=hS+s"=hS+s

Cobalah online!

Penjelasan

Penjelasan tersebut digunakan ¨untuk membatasi string (untuk menghindari pelarian yang tidak dapat dibaca):

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

Dengan menghapus fungsi, =Anda dapat memverifikasi bahwa itu memang hanya cocok dengan sumber itu sendiri.


2

> <> , 24 byte

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

Cobalah online!

Pembungkus string literal diikuti dengan memeriksa apakah input identik dengan stack, dengan pemeriksaan akhir bahwa tidak ada lagi input.


2

Jelly , 10 byte

“Ṿ;$⁼”Ṿ;$⁼

Cobalah 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

Memodifikasi default 0"D34çý"D34çýdengan menambahkan Q(periksa kesetaraan dengan input implisit)

Cobalah online.

Penjelasan:

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)

Alternatif keren 15 byte yang disediakan oleh @Grimy :

187745012D27BJQ

Cobalah online.

Penjelasan:

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
187745012D27BJQadalah dasi.
Grimmy

1

C - 186 176 karakter

Satu liner:

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

Dengan spasi putih (perhatikan bahwa ini merusak program):

*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

Runic , 11 byte

"3X4+kSqi=@

Cobalah online!

TIO mendapat pembaruan dan tidak ada lagi masalah membaca input (dan tidak lagi memerlukan spasi spasi tambahan).

Penjelasan

>                 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

Solusi JoKing:

"'<~qi=@|

Penjelasan

  <              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 Sangat pintar.
Draco18s

Sebenarnya, 9 byte menghindari rkebalikannya
Jo King

@JoKing saya mungkin seharusnya bisa sampai pada itu (dari solusi 10 byte) sendiri, tapi saya belum punya cawfee saya . Saya sudah bekerja kemarin bahwa memiliki "di sebelah kiri adalah satu-satunya tempat yang benar-benar bisa pergi, karena memilikinya di tempat lain mempersulit. (Tapi baru saja saya harus menjalankannya di debugger saya untuk melihat apa yang dilakukannya ...)
Draco18s

1

R , 54 byte

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

Cobalah online!

bodymendapatkan tubuh fungsi (membaginya sedikit, jadi itu body(f)[3]adalah segalanya dari paste0seterusnya). Menariknya, bodymemformat ulang kode, menambahkan spasi setelah koma, dll. Ini adalah kasus yang jarang terjadi pada jawaban golf R dengan spasi setelah koma.

Ini berfungsi karena body(f)merupakan objek bertipelanguage , dan ada as.charactermetode untuk tipe ini. Di sisi lain, fdan args(f)bertipe closure, dan tidak dapat dikonversi ke tipe karakter sejauh yang saya tahu. Tolong jangan tanya saya apa jenis bahasa untuk ...


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.