Bir "hile" quine


56

Uzun süredir lurker, ilk defa poster. Yani işte gidiyor.

Quine için Wikipedia sayfasında , "bir kodun kendi kaynak koduna bakarsa hile yaptığı kabul edilir" yazıyor. Senin görevin kendi kaynak kodunu okuyan bu "hile quines" birini yapmaktır.

Bu , yani bayt cinsinden en kısa kod - her dilde - kazanır. Bu, 5 baytlık bir Pyth komut dosyasının 21 baytlık bir Python komut dosyasını geçmeyeceği anlamına gelir - ancak 15 baytlık bir Python komut dosyası olacağı anlamına gelir.

Kaynak kodu okumak için G / Ç dosyasını kullanmalısınız, bu nedenle resmi Wikipedia sayfasından alınan aşağıdaki JavaScript kodu geçersiz:

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

Diskteki dosyanın kaynak koduna erişmesi gerekir .

Dosya adını belirtmenize izin verilmiyor. Dosya adının kendisini algılamasını sağlamalısınız.

Herkes temiz mi? Git!


1
Orijinal dosyada bulunmayan takip eden yeni satırlara izin veriliyor mu?
isaacg

3
@isaacg IMHO Kaynak kodu olmadığı için bu bir tane değil.
mınxomaτ

3
Kaynak konum için sabit kodlanmış bir dize varsaymak yerine, gerçek dosya adını belirlemesi gerektiğini belirtmelisiniz.
feersum

3
@Feersum ile aynı fikirdeyim, belirli bir dosya adı istemek bu zorluğu önemsiz hale getiriyor.
mınxomaτ

1
(Derlenmiş diller için) kaynak kodun aynı klasörde olduğunu varsayabiliriz (yani kaynağı almak için arg [0] 'a sadece ".cpp" veya ".hs" ekleyebiliriz).
HEGX64

Yanıtlar:


60

Zsh , 4 bayt

<$0

Z kabuğu yerleşik olarak yerleşik kedi işlevlerine sahiptir. Dördüncü karakter bir satır beslemesidir.

Çevrimiçi deneyin!

Kod hiçbir şekilde dosya adına bağlı değildir; dosya adı boşluklar veya yeni satırlar gibi özel bir karakter içeriyor olsa bile çalışır.

Test sürüşü

$ 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:)
10'da

48

Bash, 6 bayt

cat $0

Temelde.


3
Yeni bir satır yazdırmaz.
Addison Crump,

2
catYeni bir satır eklemiyor (en azından sistemimde).
Bir

7
@ isaacg cat, bayt başına verilen dosya baytının içeriğini yazdırır.
Dennis,

2
@LukStorms Ama bu bir catçözüm yerine, o zaman bir bashçözüm olmaz mıydı? Ve kedi gerçekten programlama dili olarak nitelendirilemez
Fabian Schmengler

30
Dosya adlandırılmışsa bu işe yarar -emı?
Mark Plotnick,

32

UNIX çalıştırılabilir yükleyicisi, 10 bayt

#!/bin/cat

Spam ile ilgili standart hata umursamıyorsanız, onu bir bayttan daha kısa yapabilirsiniz:

#!/bin/dd

7
Bunu severim. Olsa da, bir "dil" olarak nitelendirildiğinden emin değilim.
Kevin

Belki biraz hile yapmak, ancak yolu kısaltmak için bin klasörünüzü ve kedi programını yeniden adlandıramadınız mı?
James Webster,

3
Sana btw yapmanı önermiyorum. Sana önerdiğim şey olabilir
James Webster

3
@Kevin "Dil" (yani tercüman) cat. Ve çok spesifik olmak istersen, bir catprogram kendini basar ve var olan her dosya formatıyla uyumludur
sanırım

1
@JamesWebster sudo install /bin/cat /c. Biliyorsun, sadece /binkök dosya sisteminde değil. Bunu tek kullanıcı catolarak almalıyım…
Blacklight Shining

25

C, 52

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

Tabii ki, bu derlenmiş programı değil kaynak kodu okuyor - bunun spec içinde olduğunu varsayıyorum.


Sondaki yeni satırdan kaçınmak printfyerine kullanabilirsiniz puts.
feersum

@ feersum evet, iyi yakalama
Digital Trauma

19
@DigitalTrauma Tabiki senin avatarın yüzünden, tabii ki
Peter Olson

3
Aslında, putskullanılabilir, readdaha az karaktere ihtiyacınız var .
user4098326


13

PHP, 21 Bayt

<?=file(__FILE__)[0];

filebir dosyayı bir diziye satır satır okur ve dosyanın yalnızca bir satırı vardır. Bu karşılaştırıldığında bir bayt kaydeder readfile(__FILE__).


Bunun sadece dizi referansını destekleyen ilk sürüm olan PHP5.4 ve üstü sürümlerde çalıştığına dikkat edin. Ama bunun dışında oldukça hoş bir cevap!
Ismael Miguel

1
readfileAyrıca 21 geçerli: <?readfile(__FILE__);.
primo

1
Doğru, buna gerek yok<?=
Fabian Schmengler

12

Perl, 15 bayt

open 0;print<0>

@ ThisSuitIsBlackNot ! İle 3 bayt kurtarıldı !


2
3 bayt ile kaydedebilirsinizopen 0;print<0>
ThisSuitIsBlackNot

@BuSuitIsBlackNot Bunu yapmanın daha kısa bir yolu olmadığından emin değildim, ancak çalışmamın hayatı boyunca yapamadım ... O zaman 0varsayımları kullanmak $0?
Dom Hastings

3
Evet. Bakınız perldoc -f open: "Kısayol olarak bir bağımsız değişken çağrısı, dosya adını, dosya $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";
kimliği ile

11

Perl 6, 20 bayt

print slurp $?FILE

Perl 6 ile çok uzun zamandır çalışmamıştım, bu yüzden kısaltmak için herhangi bir püf noktası olup olmadığından emin değilim.


2
ikinci boşluğu kaldırabilir misin?
Eevee

3
@Eevee hayır, sinirleniyor
Hotkeys

11

osascript (komut satırından AppleScript), 40 33 32 bayt

(bana giden yolu oku) 'nın 1. paragrafı

İle çağrılan bir dosya üzerinde çalıştırma osascript a.

Dosyanın ilk paragrafını (satırı) alır ve izleyen bir yeni satırla, yani koddaki yeni satırıyla STDOUT'a yazdırır.



İşe almak için çalışıyor.
Addison Crump,

read path to meBenim için iş gibi görünüyor. El Cap.
Dijital Travma

Bunu görmedim, ama bu işimi bitirme şeklim. : P Teşekkürler, @ DigitalTrauma. EDIT: izleyen yeni satırlar göz önünde bulundurulmalıdır, bu nedenle yeni satır ekler ve paragraf 1'i kullanırsınız.
Addison Crump

11

Python 2,32 bayt

Dosyanın sonunda yeni bir satır var.

print open(__file__).readline()

Python 3, 33 bayt

Dosyanın sonunda yeni bir satır var.

print(open(__file__).readline())

Teşekkür etmek feersum bir sorun yakalamak ve beslemek için __file__, Loovjo 17 bayt kaydedildi Python 2 çözümüne yeni bir yaklaşım için, ve Skyler henüz başka byte kaydedilir ve Python 2. ve 3. hem çalışmış bir çözüm için (beklemede printPython bir fonksiyonu olduğu 3)!

İçin Doc bağlantısı readline


Bu aynı zamanda endparametreyi atabileceğiniz için python3'te 2 bayt kaydeder .
Skyler

@Skyler Kesinlikle haklısın.
Celeo

Bu, parens için ihtiyaç duyulan Python 3'te nasıl çalışır print?
Doorknob

Python 3'ü print(open(__file__).readline())yeni bir satır takip etmelidir .
Skyler

Python 3 örneğiniz Python 3 yerine Python 2 diyor
TheInitializer

10

Grup, yığın, parça, bir defada alınan miktar, 9 8 Bayt

@type %0

@Joshua sayesinde bir bayt kaydedildi


3
Sondaki% 'yi kaldırarak bir bayttan tasarruf edebilirsiniz.
Joshua,

10

Python 2.7, 30 bayt

print open(__file__).read(29)

Düzenleme: Açık olmak gerekirse, yukarıdaki kodun sonunda 30. bayt olarak yeni bir satıra sahip olması gerekir. Kod bloğunda nasıl görüntüleneceğini bulmak için yeterince işaretleme ile aşina değilim.

Burada aynı numarayı C gönderimdeyken kullanıyorum. Bu print, çıktıya eklenecek ek yeni satırı hesaba katacak izleyen yeni satırı hariç tüm kaynak dosyayı okur .


Bu, diğer gönderimin yaptığı sondaki yeni satırla aynı sorunu mu yaşıyor?
cole,

Hayır. Kaynak kodda 30. baytı yapan son derece yeni bir satır olması gerekiyordu, ancak kod bloğunda göstermesini sağlayamıyorum. Gönderim çalışıyor, çünkü kaynak kodun ilk 29 baytını okuyor, böylece yeni satır printdışına çıkmaz.
xsot

4
Virgülün yaptığı bu değil. Yeni satır yerine boşluk ekler.
xsot

2
anlamsal olarak önemli bir yeni hattı belirtmek için ␤ kullanabilir
Eevee

9

Java, 212 196 Bayt (sorgulanabilir kodlama kuralları olan 171 Bayt)

~ 15 byte kısaltmak için @ Cruncher sayesinde!

Bunun golfle oynayabileceğinden şüphem yok.

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

Veya, statik yöntemi (ve sınıfın adını kullanarak) başka bir yöntemle 171 bayt alırım. Yine de, bunun kodlanmış olarak nitelendirildiğinden emin değilim.

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"))));}}

Sınıf adını statik olmayan bir yöntemle almak için bir kurucu kullanır. Statik bir yöntem ( A.class.getName()) kullanmak gerçekten çok zordu, bu yüzden 'doğru' yolu kullandım. Kullanarak A.class.getName(), bu kod 171 bayta kadar kısaltır.

Okunabilir sürümleri:

Yapıcı ve kullanarak 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) {}
    }
}

Statik yöntemi kullanarak 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"))));
    }
}

Dosyanın tüm baytlarını bir kerede alır ve STDOUT'a gönderir. Oldukça basit.


Neden sadece kullanmıyorsun A.class.getName()?
Fabio F.

3
CodeGolf CodeReview değil! ;)
Fabio F.

1
@FabioF. Evet, ama kurallara aykırı bir kodlanmış dosya adı doğrultusunda dans ettiğini düşünüyorum. Mesele şu ki, eğer dosyanın ismini değiştirirseniz, sınıfın ismini (belli ki) değiştirmelisiniz, fakat aynı zamanda bir hardcoded dosya ismi gibi olan bu satırı da değiştirmelisiniz.
Cruncher

1
Yapıcı içindeki print deyimini arayarak statik bir değişken ayarlamaktan kurtulamıyor musunuz?
Cruncher

1
@Cruncher Nah. Java.io 'yu elde edersiniz, ben java.nio' ya sadık kalacağım - nokta kazanmak değil, fakat bunu farklı yöntemlerle son derece net bir şekilde yapmanın yollarını gösterir.
Addison Crump,

8

AutoIt, 34 bayt

Kendini panoya çıkarır:

ClipPut(FileRead(@ScriptFullPath))


7

Go, 111 105 bayt

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

Go'daki ilk golf kodlarım - burada kullanabileceğiniz birkaç püf noktası.


Go'da zaten bir cevap var - bu aynı yöntemi kullanıyor mu?
Addison Crump,

@VoteToClose: Farkındayım, diğerinden esinlendim, ama burada stdout'a dosya açmak ve pipinglemek için farklı teknik ve burada yeniden adlandırma paketi (ucuz hile) kullandım. Bana büyük bir 22 bayt
kurtardı

Yöntem aslında biraz farklı, iyi olanı!
Fabian Schmengler

7

PowerShell, 39 36 31 25 Bayt

Alabildiğim kadar sıkı:

gc $MyInvocation.MyCommand.Path | oh

Popüler talebin desteğiyle bu, şu şekilde değiştirildi:

gc $PSCommandPath|echo -n

ana akım standart çıkışını barındırmak için yazdırır .


gc $MyInvocation.MyCommand.Pathyeterlidir. Otomatik olarak yazdırır.
Andrew,

özellikle senaryo sessizce çalışıyorsa garanti edilmez
Chad Baxter

Haha evet umrumda değil. Başka kimsede PowerShell cevabı yoksa gönderecektim. Ama bunun gcbir takma ad olduğunu ve sadece kullanacağını unuttum cat, bu yüzden zaten orada bir bayt vardı.
Andrew,

Bu konuda o kadar katı olmazdım. Aksi takdirde, her PS cevabı açıkça ev sahibinin kabuğuna yönlendirmek zorunda kalacaktı, ama bu size bağlı ...
Andrew

Bunun yerine gc $PSCommandPath17 bayt kullanabilirsiniz . Gördüğüm sorun, bunun (kaynakta bulunmayan) yeni bir çizgiyi yaymasıdır. Şimdi izleyen newline tamamsa veya olmazsa ... bu kuralın ne olduğuna bağlı olarak, gc $PSCommandPath|write-host -n31 bayt gibi hileli bir şey yapmamız gerekebilir .
AdmBorkBork,


5

C, 49 bayt

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

Düzenleme: Netleştirmek için, 49. bayt yeni bir satırdır.

Bu puts, çıktının sonuna eklenecek olan yeni satırı hesaba katan kaynak kodunu eksi sondaki yeni satırı okur .


Bu kod tanımsız davranışa iki kez çağrı yapar.
Joshua,

5
Bu kod golf. Kodum istenen çıktıyı üretiyor, bu yüzden geçerli bir gönderi.
xsot

1
@ xsot Bu durumda, muhtemelen derleyici sürüm + seçeneklerini listelemelisiniz; Aksi halde bu doğrulanamayabilir.
Justin,

1
Eğer tanımlanmamış davranışa izin verilirse, ayın bazı evrelerinde bazı makinelerde istenen çıktıyı üreten bir derleyiciye sahip olduğunuz sürece izin verilirse, int main (void) {* 0; } bir çözüm olarak. Ne de olsa, standart, sorunu çözen bir programda derleyen bir uygulamaya izin verir. Derleyiciyi belirlediğiniz sürece uygulamaya bağlı davranışı kullanmakta iyi olurum, ancak tanımsız davranışta, arka arkaya on kez koştuysanız on farklı cevap almadığınızı bile garanti edemezsiniz. Aynı makine
Ray

1
@ MDXF Cidden bu çözümü yazmamızı önermek istemedim. Tanımlanamayan davranışa izin vermeye karşı çıkmıştım. int main() {*0;} belki o tanımsız davranış içerdiğinden, hatta mevcut derleyiciler üzerinde çalışmak. Benzer şekilde, xsot çözümü olabilir tanımsız davranış içerdiğinden, varolan derleyiciler üzerinde çalışmak. Hiçbirinin sorunu çözeceği garanti edilmez. (Xsot'ların kuşkusuz bunu yapma olasılığı daha yüksek olmasına rağmen , bu kadar kolay çökebilir). Asıl iddiam, uygulamaya bağlı veya tanımlanmamış davranışa dayanan ancak tanımlanmamış davranışa bağlı çözümlere izin vermemiz gerektiğidir.
Ray


4

Pyth, 25 bayt

$import sys$h'e$sys.argv

Bu dosya adını okur. Temelde argv'ye bakar, son argümanına karşılık gelen dosyayı açar ve ilk satırını yazdırır.


Yapamaz h'$__file__$mısın
kirbyfan64sos

@ kirbyfan64sos Bu bana hata veriyor NameError: name '__file__' is not defined. Pyth, Python'a derlenir ve sonra sonuç dizgisi yürütülür. Bu yüzden çalışmasını beklemem.
isaacg

4

Git, 133 Bayt

Herkes temiz mi? Git!

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

2
Bu bana Go'daki kendi (ve ilk) kod-golf çözümünü yazmam için ilham verdi. Bazı genel püf noktaları ararken, örneğin paketler için tek harfli isimler kullanarak buradaki 123 karaktere kolayca gidebilirsiniz r"runtime".
tomasz

4

> <> , 13 Bayt

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

Hem çevrimiçi hem de çevrimdışı tercümanlar üzerinde test edilmiştir. gKomut kaynak dosyadan okumak için ve bu meydan amacıyla sayılmaz eğer olmayan rakip benim girişini işaretlemek edeceğiz edememek en yakın olan; Normalde quines için "hile" olarak kabul edildiğine inanıyorum.

Çevrimiçi deneyin.


4

Haskell, 63 bayt

Bilim için!

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

Sadece runhaskellkomutla çalışır . Yine de çok havalı
HEGX64

4

> <> , 31 bayt

Yasal Uyarı:> <> içinde dosya G / Ç yoktur, ancak ilham alan dilden>>> Befunge'den devralınan kod alanı G / Ç'sini sergilemenin ilginç olacağını düşündüm.

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

Kendi kendine okuyan Quine Bir süre önce yaptığım, burada deneyebilirsiniz .

Sadece daha kısa bir kendi kendine okuma özeti olduğunu gördüm . Kod-golf standartlarında açıkça daha iyi olsa da, kod uzunluğunun kod uzunluğuna sahip olduğunu belirtmek isterim; benimki ise ek satırları veya kod sütunlarını kopyalar (orijinal kodu bozmadıkları sürece).


> <>
Yazmayı

@ Sp3000 gerçekten çalıyor, meydan okumayı yeterince iyi okumamış gibiyim. Bir feragatname ekleyeceğim
Aaron

3

F #, 54 Bayt

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

Kullanımı:

fsi --exec a.fsx

3

Perl 5, 15 13 bayt

Buna ilham vermek için Bash çözümüne teşekkür ederiz:

print`cat $0`

EDIT: Yarı-kolon veya ilk boşluğa gerek yok.


Saf olmayan perl, içinde catmevcut ve erişilebilir olan başka bir çalıştırılabilir dosyaya ihtiyaç duyar $PATH. Fakat eğer mevcutsa, sadece mevcut bir komut olarak kabul edilebilir perl, öyleyse neden olmasın.
Golar Ramblar

3

Node.js, 66 63 bayt

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

Kullanmaz console.logYeni satır ekler, hangi.


1
Eşzamanlı api kullanarak birkaç bayt kaydedebilirsiniz:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike

1
console.log(require('fs').readFileSync(process.argv[1]))\n57 bayt neden olmasın ?
Conor O'Brien

Bu her zaman işe yaramaz. Dosyanın ismini söyle test.js. Çalıştırarak çağırmak için geçerlidir node test, bu bir hata yapmasına neden olur.
Patrick Roberts


3

Haskell , 49 bayt

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

Çevrimiçi deneyin!

(GHC) Haskell, C ön işlemcisini kullanmak için bir uzantıya sahiptir (genellikle sürümler ve mimariler arasında taşınabilirlik için kullanılır.) Umarım kendi kendini açıklayıcıdır.


3

JavaScript içeren HTML, 115 bayt (gerçekten sayılmaz)

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

Bu sayılır mı? Aldırmıyorum, eğlenceliydi :)

Teknik olarak bir dosya açmıyor. Aynı zamanda iyi oluşturulmuş bir HTML5 belgesidir. XMLSerializer, DOCTYPE bölümünü de iade eden, ancak standart olmayan tek araçtı. Yine de, krom ve firefox'ta çalışır ve diğer tarayıcılara da bahse girerim.

Ve bir bonus olarak:

JavaScript, 41 bayt

alert(document.currentScript.textContent)

Kaldır ";" sonunda, 1 byte tasarruf edin :)
Евгений Новиков

1
@ ЕвгенийНовиков Haklısın, o zaman neden arkada bıraktığımdan emin değilsin. Yine de saymadım gibi görünüyor.
Domino
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.