Quine "curang"


56

Lurker lama, poster pertama kali. Jadi begini.

Di halaman Wikipedia untuk quine , dikatakan bahwa "quine dianggap 'curang' jika melihat kode sumbernya sendiri." Tugas Anda adalah membuat salah satu dari "quating quines" yang membaca kode sumbernya sendiri.

Ini adalah , jadi kode terpendek dalam byte - dalam setiap bahasa - menang. Ini berarti bahwa skrip Pyth 5 byte tidak akan mengalahkan skrip Python 21 byte - tetapi skrip Python 15 byte akan melakukannya.

Anda harus menggunakan file I / O untuk membaca kode sumber, jadi kode JavaScript berikut, yang diambil dari halaman Wikipedia resmi, tidak valid:

function a() {
    document.write(a, "a()");
}
a()

Itu harus mengakses kode sumber file pada disk .

Anda tidak diizinkan menentukan nama file. Anda harus membuatnya mendeteksi nama file itu sendiri.

Semuanya bersih? Pergi!


1
Apakah trailing baris baru tidak ada dalam file asli diizinkan?
isaacg

3
@isaacg IMHO Itu bukan quine, karena itu bukan kode sumber.
mınxomaτ

3
Anda harus menyatakan persyaratan yang menentukan nama file yang sebenarnya alih-alih mengasumsikan string yang dikodekan untuk lokasi sumber.
feersum

3
Saya setuju dengan @feersum, bahwa membutuhkan nama file tertentu membuat tantangan ini menjadi sepele.
mınxomaτ

1
Bisakah kita berasumsi bahwa (untuk bahasa yang dikompilasi) kode sumber ada di folder yang sama (yaitu kita bisa menambahkan ".cpp" atau ".hs" ke arg [0] untuk mendapatkan sumbernya).
HEGX64

Jawaban:


60

Zsh , 4 byte

<$0

Shell Z memiliki fungsionalitas kucing built-in. Karakter keempat adalah linefeed.

Cobalah online!

Kode sama sekali tidak bergantung pada nama file; ini berfungsi bahkan jika nama file berisi karakter khusus, seperti spasi atau baris baru.

Uji coba

$ cat "my quine.sh"
<$0
$ zsh "my quine.sh" 
<$0
$ diff -s <(zsh "my quine.sh") <(cat "my quine.sh")
Files /dev/fd/63 and /dev/fd/62 are identical

28
feline functionalities:)
theB

48

Bash, 6 byte

cat $0

Pada dasarnya


3
Itu tidak mencetak baris baru.
Addison Crump

2
cattidak menambahkan baris baru (setidaknya di sistem saya).
spaghetto

7
@isaacg catmencetak konten byte file yang disediakan per byte.
Dennis

2
@LukStorms Tapi bukankah ini catsolusi, bukan bashsolusi? Dan kucing tidak benar-benar memenuhi syarat sebagai bahasa pemrograman
Fabian Schmengler

30
Apakah ini akan berfungsi jika file tersebut dinamai -e?
Mark Plotnick

32

Loader yang dapat dieksekusi UNIX, 10 byte

#!/bin/cat

Jika Anda tidak peduli tentang spam pada kesalahan standar, Anda bisa membuatnya lebih pendek satu byte:

#!/bin/dd

7
Saya suka ini. Tidak yakin apakah itu memenuhi syarat sebagai "bahasa,".
Kevin

Mungkin sedikit curang, tetapi tidak bisakah Anda mengganti nama folder bin dan program kucing untuk mempersingkat jalur?
James Webster

3
Saya tidak menyarankan Anda melakukan btw. Saya sarankan Anda bisa
James Webster

3
@Kevin "Bahasa" (yaitu, juru bahasa) adalah cat. Dan saya kira jika Anda ingin menjadi sangat spesifik, sebuah catprogram cukup mencetak sendiri, dan kompatibel dengan setiap format file yang ada :)
l0b0

1
@ JamesWebster sudo install /bin/cat /c. Kau tahu, kalau-kalau /bintidak ada di sistem file root. Harus memilikinya catdalam pengguna tunggal ...
Blacklight Shining

25

C, 52

s[99];main(){read(open(__FILE__,0),s,99);printf(s);}

Tentu saja, ini membaca kode sumber dan bukan program yang dikompilasi - saya berasumsi itu dalam spesifikasi.


Anda dapat menggunakan printfalih-alih putsuntuk menghindari baris baru yang tertinggal.
feersum

@feersum ya, tangkapan bagus
Digital Trauma

19
@DigitalTrauma Itu karena avatar Anda, tentu saja
Peter Olson

3
Sebenarnya, putsbisa digunakan, Anda hanya perlu readkarakter yang lebih sedikit.
user4098326


13

PHP, 21 Bytes

<?=file(__FILE__)[0];

filemembaca baris demi baris file menjadi array dan file hanya memiliki satu baris. Ini menghemat satu byte dibandingkan dengan readfile(__FILE__).


Perhatikan bahwa ini hanya bekerja dari PHP5.4 dan lebih tinggi, yang merupakan versi pertama yang mendukung de-referensi array. Namun selain itu, jawaban yang cukup bagus!
Ismael Miguel

1
readfilejuga 21: <?readfile(__FILE__);.
primo

1
Benar, tidak perlu<?=
Fabian Schmengler 3-15

12

Perl, 15 byte

open 0;print<0>

Disimpan 3 byte berkat @ ThisSuitIsBlackNot !


2
Anda dapat menyimpan 3 byte denganopen 0;print<0>
ThisSuitIsBlackNot

@ ThisSuitIsBlack Tidakkah saya yakin ada cara yang lebih pendek untuk melakukannya, tapi saya tidak bisa selama pekerjaan saya menyelesaikannya ... Menggunakan 0asumsi $0lalu?
Dom Hastings

3
Ya. Lihat perldoc -f open: "Sebagai pintasan panggilan satu argumen mengambil nama file dari variabel skalar global dengan nama yang sama dengan filehandle: $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";"
ThisSuitIsBlackNot

11

Perl 6, 20 byte

print slurp $?FILE

Saya belum pernah bekerja dengan Perl 6 terlalu lama, jadi saya tidak yakin apakah ada trik untuk membuatnya lebih pendek.


2
Bisakah Anda menghapus ruang kedua?
Eevee

3
@Eevee tidak, itu menjadi marah
Hotkeys

11

osascript (AppleScript dari baris perintah), 40 33 32 byte

(baca jalur ke saya) paragraf 1

Menjalankan pada file yang disebut dengan osascript a.

Mendapat paragraf pertama (baris) file dan mencetaknya ke STDOUT dengan baris baru, sehingga baris baru dalam kode.


1
Lihat hasil edit saya ke OP
TheInitializer

Bekerja untuk membuatnya bekerja.
Addison Crump

read path to mesepertinya bekerja untuk saya. El Cap.
Trauma Digital

Tidak melihat ini, tetapi inilah cara saya akhirnya melakukannya. : P Terima kasih, @DigitalTrauma. EDIT: mengikuti baris baru harus dipertimbangkan, jadi Anda menambahkan baris baru dan menggunakan paragraf 1.
Addison Crump

11

Python 2, 32 byte

Ada baris baru di akhir file.

print open(__file__).readline()

Python 3, 33 byte

Ada baris baru di akhir file.

print(open(__file__).readline())

Berkat feersum untuk menangkap masalah dan penyediaan __file__, Loovjo untuk pendekatan baru pada solusi Python 2 yang menghemat 17 byte, dan Skyler untuk solusi yang menyimpan byte lain dan bekerja di Python 2 dan 3 (tertunda)print fungsi pada Python 3)!

Tautan dokumen untuk readline


Ini juga akan menghemat 2 byte di python3 karena Anda bisa membuang endparameter.
Skyler 2-15

@ Skyler Anda benar sekali.
Celeo

Bagaimana cara kerjanya di Python 3, yang membutuhkan parens print?
Gagang Pintu

Python 3 harus print(open(__file__).readline())diikuti oleh baris baru.
Skyler 2-15

Contoh Python 3 Anda mengatakan Python 2 daripada Python 3
TheInitializer

10

Batch, 9 8 Bytes

@type %0

Menyimpan satu byte berkat @ Yosua


3
Anda dapat menyimpan byte dengan menghilangkan trailing%.
Joshua

10

Python 2.7, 30 byte

print open(__file__).read(29)

Sunting: Hanya untuk menjadi jelas, kode di atas seharusnya memiliki baris baru pada akhirnya sebagai byte ke-30. Saya tidak terbiasa dengan penurunan harga cukup untuk mengetahui cara menampilkannya di blok kode.

Saya menggunakan trik yang sama di sini seperti yang ada di pengiriman C saya. Ini membaca seluruh file sumber tidak termasuk baris baru yang tertinggal ke akun untuk baris baru tambahan yang printakan ditambahkan ke output.


Apakah ini mengalami masalah yang sama dengan trailing newline yang dilakukan pengajuan lainnya?
cole

Tidak. Seharusnya ada trailing newline yang membuat byte ke-30 dalam kode sumber tetapi saya tidak bisa menampilkannya di blok kode. Kiriman saya berfungsi karena membaca 29 byte pertama dari kode sumber sehingga baris baru dari printtidak akan asing.
xsot

4
Bukan itu yang dilakukan oleh koma. Ini menambahkan ruang alih-alih baris baru.
xsot

2
dapat menggunakan ␤ untuk menunjukkan baris baru yang sangat penting secara semantik
Eevee

9

Java, 212 196 Bytes (171 Bytes dengan aturan hard-coding yang dipertanyakan)

Terima kasih kepada @Cruncher untuk mempersingkatnya ~ 15 byte!

Saya tidak ragu ini bisa golf.

import java.nio.file.*;class A{public static void main(String[]a){new A();}A(){try{System.out.print(new String(Files.readAllBytes(Paths.get(getClass().getName()+".java"))));}catch(Exception e){}}}

Atau, metode lain, menggunakan metode statis (dan nama kelas), saya mendapatkan 171 byte. Saya tidak yakin apakah ini memenuhi syarat sebagai hard-coded.

import java.nio.file.*;class A{public static void main(String[]a)throws Exception{System.out.print(new String(Files.readAllBytes(Paths.get(A.class.getName()+".java"))));}}

Menggunakan konstruktor untuk mendapatkan nama kelas dengan metode non-statis. Menggunakan metode statis ( A.class.getName()) sangat sulit dikodekan, jadi saya menggunakan cara yang 'tepat'. Dengan menggunakan A.class.getName(), kode ini lebih pendek menjadi 171 byte.

Versi yang dapat dibaca:

Menggunakan konstruktor dan this.getClass():

import java.nio.file.*;
class A{
    public static void main(String[]a) {
        new A();
    }
    A(){
        try{
            System.out.print(
                new String(
                Files.readAllBytes(
                Paths.get(
                getClass().getName()+".java"))));
        }
        catch(Exception e) {}
    }
}

Menggunakan metode statis A.class.getName():

import java.nio.file.*;
class A {
    public static void main(String[] a) throws Exception {
        System.out.print(
             new String(
                  Files.readAllBytes(
                       Paths.get(
                            A.class.getName()+".java"))));
    }
}

Raih semua byte file sekaligus dan output ke STDOUT. Cukup mudah.


Kenapa tidak digunakan A.class.getName()?
Fabio F.

3
Ini CodeGolf bukan CodeReview! ;)
Fabio F.

1
@FabioF. Ya, tapi saya pikir itu menari di baris menjadi nama file yang dikodekan, yang melanggar aturan. Intinya adalah, jika Anda mengubah nama file, Anda harus mengubah nama kelas (jelas), tetapi juga mengubah baris ini, yang seperti nama file yang di-hardcode.
Cruncher

1
Tidak bisakah Anda memanggil pernyataan cetak di dalam konstruktor dan menyelamatkan diri dari pengaturan variabel statis?
Cruncher

1
@Cruncher Nah. Anda mendapatkan java.io, saya akan tetap menggunakan java.nio - intinya bukan untuk menang, tetapi tunjukkan cara untuk melakukannya dengan sangat ringkas dengan metode yang berbeda.
Addison Crump

8

AutoIt, 34 byte

Output sendiri ke clipboard:

ClipPut(FileRead(@ScriptFullPath))


7

Pergi, 111 105 byte

package main
import("io"
."os"
."runtime")
func main(){_,p,_,_:=Caller(0)
f,_:=Open(p)
io.Copy(Stdout,f)}

Golf kode pertama saya di Go - hanya beberapa trik yang dapat Anda gunakan di sini.


Sudah ada jawaban di Go - apakah ini menggunakan metode yang sama?
Addison Crump

@VoteToClose: Saya sadari, saya memang terinspirasi oleh yang lain, tetapi menggunakan nama paket di sini (trik murah) serta teknik berbeda untuk membuka dan mengirim file ke stdout. Menyelamatkan saya
tomasz

Metode ini sebenarnya sedikit berbeda, bagus!
Fabian Schmengler

7

PowerShell, 39 36 31 25 Bytes

Tentang sekencang yang saya bisa mendapatkannya:

gc $MyInvocation.MyCommand.Path | oh

Didukung oleh permintaan populer, ini telah diubah menjadi:

gc $PSCommandPath|echo -n

mencetak ke host keluaran standar shell .


gc $MyInvocation.MyCommand.Pathcukup. Ini akan secara otomatis mencetaknya.
Andrew

itu tidak dijamin terutama jika skrip berjalan diam
Chad Baxter

Haha ya saya tidak peduli. Saya akan memposting jika tidak ada orang lain yang memiliki jawaban PowerShell. Tapi saya lupa itu gcadalah alias dan hanya akan digunakan cat, jadi Anda punya byte pada saya di sana.
Andrew

Eh, aku tidak akan seketat itu. Kalau tidak, setiap jawaban PS secara eksplisit harus disalurkan ke shell host, tetapi itu terserah Anda ...
Andrew

Anda bisa menggunakan gc $PSCommandPath17 byte. Masalah yang saya lihat adalah bahwa ini memunculkan baris baru (yang tidak ada di sumber). Ini ambigu sekarang jika membuntuti baris baru OK atau tidak ... tergantung bagaimana aturan itu, kita mungkin perlu melakukan sesuatu yang rumit seperti gc $PSCommandPath|write-host -nuntuk 31 byte.
AdmBorkBork


5

C, 49 byte

s[];main(){read(open(__FILE__,0),s,48);puts(s);}

Sunting: Untuk memperjelas, byte ke-49 adalah baris baru.

Ini membaca kode sumber minus baris baru di akhir akun untuk baris baru yang putsakan ditambahkan ke akhir output.


Kode ini memanggil perilaku tidak terdefinisi dua kali.
Joshua

5
Nah, ini kode golf. Kode saya menghasilkan output yang diinginkan sehingga ini adalah pengiriman yang valid.
xsot

1
@xsot Dalam kasus itu, Anda mungkin harus mendaftar versi + opsi kompiler; jika tidak, ini mungkin tidak dapat diverifikasi.
Justin

1
Jika memiliki perilaku tidak terdefinisi diizinkan selama Anda dapat memiliki beberapa kompiler yang menghasilkan output yang diinginkan pada beberapa mesin selama beberapa fase bulan, maka saya usulkan int main (void) {* 0; } sebagai solusi. Setelah semua, standar akan mengizinkan implementasi yang mengkompilasi itu menjadi program yang memecahkan masalah. Saya akan baik-baik saja dengan menggunakan perilaku yang bergantung pada implementasi selama Anda menentukan kompiler, tetapi dengan perilaku yang tidak terdefinisi, Anda bahkan tidak dapat menjamin bahwa Anda tidak akan mendapatkan sepuluh jawaban yang berbeda jika Anda menjalankannya sepuluh kali berturut-turut di mesin yang sama.
Ray

1
@ MDXF Saya tidak serius menyarankan agar kami menulis solusi itu. Saya berdebat menentang membiarkan perilaku yang tidak terdefinisi. int main() {*0;} mungkin bekerja bahkan pada kompiler yang ada, karena mengandung perilaku yang tidak terdefinisi. Demikian pula, solusi xsot mungkin berfungsi pada kompiler yang ada, karena berisi perilaku yang tidak terdefinisi. Tidak ada yang dijamin untuk menyelesaikan masalah. (Meskipun xsot memang diakui lebih cenderung melakukannya, mungkin saja mudah crash). Argumen saya yang sebenarnya adalah bahwa kita harus mengizinkan solusi yang bergantung pada implementasi atau perilaku yang tidak ditentukan, tetapi tidak perilaku yang tidak ditentukan.
Ray

5

Mathematica, 16 byte

FilePrint@$Input

Jalankan dalam mode skrip .


Saya telah menggunakan Mathematica selama bertahun-tahun dan bahkan belum pernah mendengar tentang mode skrip.
Michael Stern

4

Pyth, 25 byte

$import sys$h'e$sys.argv

Ini membaca nama file-nya. Pada dasarnya, ia mencari argv, membuka file yang sesuai dengan argumen terakhirnya, dan mencetak baris pertama.


Tidak bisakah kamu melakukannya h'$__file__$?
kirbyfan64sos

@ kirbyfan64sos Itu memberi saya kesalahan NameError: name '__file__' is not defined. Pyth dikompilasi ke Python, dan kemudian string yang dihasilkan dieksekusi. Jadi saya tidak berharap itu berhasil.
isaacg

4

Pergi, 133 Bytes

Semuanya bersih? Pergi!

package main
import("fmt"
"io/ioutil"
"runtime")
func main(){_,f,_,_:=runtime.Caller(0)
s,_:=ioutil.ReadFile(f)
fmt.Print(string(s))}

2
Ini mengilhami saya untuk menulis solusi kode-golf saya sendiri (dan yang pertama) di Go. Mencari beberapa trik umum, Anda dapat dengan mudah turun ke 123 karakter di sini dengan menerapkan nama huruf tunggal untuk paket, misalnya r"runtime".
tomasz

4

> <> , 13 Bytes

0:0go:c=?;1+!

Diuji baik pada penerjemah online dan offline. Itug perintah adalah yang paling dekat untuk dapat membaca dari file sumber dan jika tidak dihitung untuk tujuan tantangan ini saya akan menandai entri saya non-bersaing; Saya percaya itu biasanya dianggap "curang" untuk quines.

Cobalah online.


4

Haskell, 63 byte

Untuk sains!

import System.Environment
main=getProgName>>=readFile>>=putStr

Hanya berfungsi dengan runhaskellperintah. Sangat keren
HEGX64

4

> <> , 31 byte

Penafian: tidak ada file I / O di> <>, namun saya pikir akan menarik untuk memamerkan ruang kode I / O yang diwarisi dari Befunge, salah satu bahasa yang menginspirasi> <>.

00voa0+1;!?$~<
1+> :r:@g: ?!^o$

Quine yang membaca sendiri yang saya buat beberapa waktu lalu, Anda dapat mencobanya di sini .

Saya baru saja melihat ada quine membaca pendek> <> . Walaupun jelas lebih baik dalam standar kode-golf, saya ingin menunjukkan bahwa kode itu memiliki panjang kode yang dikodekan, sedangkan milik saya akan menyalin baris tambahan atau kolom kode (selama mereka tidak melanggar kode asli).


Saya berpikir untuk memposting di> <>, tetapi saya pikir> <> tidak mungkin karena aturan: "Anda harus menggunakan file I / O untuk membaca kode sumber"
Sp3000

@ Sp3000 woops memang, sepertinya saya tidak membaca tantangan dengan cukup baik. Saya akan menambahkan penafian
Aaron

3

F #, 54 Bytes

printf"%s"(System.IO.File.ReadAllText __SOURCE_FILE__)

Pemakaian:

fsi --exec a.fsx

3

Perl 5, 15 13 byte

Kredit untuk solusi Bash untuk menginspirasi ini:

print`cat $0`

EDIT: Tidak perlu semi-kolon atau spasi pertama.


Tidak perl murni, perlu beberapa executable lainnya, yaitu cat, sekarang dan dapat ditemukan di Internet $PATH. Tetapi jika ada, itu dapat dianggap hanya sebagai perintah yang tersedia perl, jadi mengapa tidak.
Golar Ramblar

3

Node.js, 66 63 byte

p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))

Tidak digunakan console.log, yang menambahkan baris baru.


1
Anda dapat menyimpan beberapa byte dengan menggunakan api sinkron:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike

1
Kenapa tidak console.log(require('fs').readFileSync(process.argv[1]))\nuntuk 57 byte?
Conor O'Brien

Ini tidak selalu berhasil. Katakanlah file tersebut bernama test.js. Ini valid untuk menjalankannya dengan menjalankan node test, yang akan menyebabkan ini membuang kesalahan.
Patrick Roberts

3

C, 31 byte

main(){system("cat "__FILE__);}

Solusi bash sangat singkat, jadi mengapa tidak mendasarkan solusi C di atasnya?


3

Haskell , 49 byte

{-#LANGUAGE CPP#-}main=putStr=<<readFile __FILE__

Cobalah online!

(GHC) Haskell memiliki ekstensi untuk menggunakan preprocessor C (biasanya digunakan untuk portabilitas antara versi dan arsitektur.) Mudah-mudahan cukup jelas.


3

HTML dengan JavaScript, 115 byte (tidak benar-benar masuk hitungan)

<!DOCTYPE html><html><title>x</title><script>alert(new XMLSerializer().serializeToString(document))</script></html>

Apakah ini masuk hitungan? Saya tidak keberatan, itu menyenangkan :)

Secara teknis itu tidak membuka file. Ini juga merupakan dokumen HTML5 yang baik. XMLSerializer adalah satu-satunya alat yang juga mengembalikan porsi DOCTYPE, tetapi tidak standar. Tetap saja, ini bekerja pada chrome dan firefox, dan saya bertaruh browser lain.

Dan sebagai bonus:

JavaScript, 41 byte

alert(document.currentScript.textContent)

Hapus ";" pada akhirnya, simpan 1 byte :)
Евгений Новиков

1
@ ЕвгенийНовиков Anda benar, tidak yakin mengapa saya meninggalkannya saat itu. Sepertinya saya tidak menghitungnya.
Domino
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.