Ein "Betrug" quine


56

Langjähriger Lauerer, erstmaliges Poster. Also geht es los.

Auf der Wikipedia-Seite für quine heißt es, dass "ein quine als 'betrügerisch' angesehen wird, wenn es seinen eigenen Quellcode betrachtet." Ihre Aufgabe ist es, eine dieser "Cheating Quines" zu erstellen, die ihren eigenen Quellcode liest.

Das ist , also gewinnt der kürzeste Code in Bytes - in jeder Sprache . Dies bedeutet, dass ein 5-Byte-Python-Skript kein 21-Byte-Python-Skript übertrifft, sondern ein 15-Byte-Python-Skript.

Sie müssen Datei-E / A verwenden, um den Quellcode zu lesen. Daher ist der folgende JavaScript-Code von der offiziellen Wikipedia-Seite ungültig:

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

Es muss auf den Quellcode der Datei auf der Festplatte zugreifen .

Sie dürfen den Dateinamen nicht angeben. Sie müssen dafür sorgen, dass der Dateiname selbst erkannt wird.

Jeder klar? Gehen!


1
Ist ein abschließender Zeilenumbruch nicht in der Originaldatei erlaubt?
Isaacg

3
@isaacg IMHO Das ist kein Quine, da es nicht der Quellcode ist.
Mittwoch,

3
Sie sollten festlegen, dass der tatsächliche Dateiname ermittelt wird, anstatt eine fest codierte Zeichenfolge für den Quellspeicherort anzunehmen.
Feersum

3
Ich stimme jedoch mit @feersum überein, dass das Erfordernis eines bestimmten Dateinamens diese Herausforderung trivial macht.
Mittwoch,

1
Können wir annehmen, dass sich der Quellcode (für kompilierte Sprachen) im selben Ordner befindet (dh wir können einfach ".cpp" oder ".hs" zu arg [0] hinzufügen, um den Quellcode zu erhalten)?
HEGX64

Antworten:


60

Zsh , 4 Bytes

<$0

Die Z-Shell verfügt über integrierte Funktionen für Katzen. Das vierte Zeichen ist ein Zeilenvorschub.

Probieren Sie es online!

Der Code hängt in keiner Weise vom Dateinamen ab. Dies funktioniert auch dann, wenn der Dateiname Sonderzeichen wie Leerzeichen oder Zeilenumbrüche enthält.

Testlauf

$ 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 Bytes

cat $0

Grundsätzlich gilt.


3
Es wird keine neue Zeile gedruckt.
Addison Crump

2
catfügt keine neue Zeile hinzu (zumindest auf meinem System).
ein Spaghetto

7
@isaacg catdruckt den Inhalt der angegebenen Datei byteweise aus.
Dennis

2
@LukStorms Aber wäre das dann nicht eine catLösung statt einer bashLösung? Und Katze nicht wirklich als Programmiersprache zu qualifizieren
Fabian Schmengler

30
Funktioniert das, wenn die Datei benannt ist -e?
Mark Plotnick

32

Ausführbarer UNIX-Loader, 10 Byte

#!/bin/cat

Wenn Ihnen Spam bei Standardfehlern egal ist, können Sie ihn um ein Byte kürzer machen:

#!/bin/dd

7
Ich mag das. Ich bin mir jedoch nicht sicher, ob es sich um eine "Sprache" handelt.
Kevin

Vielleicht ein bisschen schummeln, aber konnten Sie Ihren bin-Ordner und das cat-Programm nicht umbenennen, um den Pfad zu verkürzen?
James Webster

3
Ich schlage nicht vor, Sie tun übrigens. Ich schlage vor, Sie könnten
James Webster

3
@ Kevin Die "Sprache" (das heißt, Dolmetscher) ist cat. Und ich denke, wenn Sie sehr spezifisch sein wollen, catdruckt sich ein Programm einfach von selbst und ist mit jedem existierenden Dateiformat kompatibel :)
l0b0

1
@ JamesWebster sudo install /bin/cat /c. Weißt du, nur für den Fall, dass /bines sich nicht um das Root-Dateisystem handelt. catMuss ich in Singleuser haben ...
Blacklight Shining

25

C 52

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

Dies liest natürlich den Quellcode und nicht das kompilierte Programm - ich gehe davon aus, dass dies innerhalb der Spezifikation liegt.


Sie können printfstattdessen verwenden puts, um eine nachgestellte Zeile zu vermeiden.
Feersum

@feersum ja, guter Fang
Digital Trauma

19
@DigitalTrauma Es liegt natürlich an deinem Avatar
Peter Olson

3
Tatsächlich putskann verwendet werden, dass Sie nur readweniger Zeichen benötigen .
user4098326


13

PHP, 21 Bytes

<?=file(__FILE__)[0];

fileLiest eine Datei zeilenweise in ein Array und die Datei hat nur eine Zeile. Das spart ein Byte im Vergleich zu readfile(__FILE__).


Beachten Sie, dass dies nur ab PHP5.4 funktioniert. Dies war die erste Version, die die Dereferenzierung von Arrays unterstützte. Aber ansonsten eine ganz nette Antwort!
Ismael Miguel

1
readfileist auch 21: <?readfile(__FILE__);.
Primo

1
Richtig, das braucht es nicht<?=
Fabian Schmengler

12

Perl, 15 Bytes

open 0;print<0>

3 Bytes gespart dank @ ThisSuitIsBlackNot !


2
Sie können 3 Bytes mitopen 0;print<0>
ThisSuitIsBlackNot

@ThisSuitIsBlackNot Ich war sicher , dass es ein kürzerer Weg war , es zu tun, aber ich kann es nicht für das Leben meiner Arbeit ... Mit übernehme dann? 0$0
Dom Hastings

3
Ja. Siehe perldoc -f open: "Als Abkürzung übernimmt ein Aufruf mit einem Argument den Dateinamen von der globalen skalaren Variablen mit demselben Namen wie das Dateihandle: $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";"
ThisSuitIsBlackNot

11

Perl 6, 20 Bytes

print slurp $?FILE

Ich habe nicht sehr lange mit Perl 6 gearbeitet, daher bin ich mir nicht sicher, ob es irgendwelche Tricks gibt, um dies zu verkürzen.


2
Kannst du das zweite Leerzeichen entfernen?
Eevee

3
@Eevee nein, es wird wütend
Hotkeys

11

osascript (AppleScript von der Kommandozeile), 40 33 32 Bytes

(lies den Pfad zu mir) 's Absatz 1

Ausführen einer Datei mit dem Namen a mit osascript a.

Ruft den ersten Absatz (die erste Zeile) der Datei ab und druckt ihn mit einer nachfolgenden neuen Zeile in STDOUT aus, daher die neue Zeile im Code.


1
Siehe meine
Änderung

Ich arbeite daran, es zum Laufen zu bringen.
Addison Crump

read path to mescheint für mich zu arbeiten. El Cap.
Digitales Trauma

Ich habe das nicht gesehen, aber so bin ich zum Schluss gekommen. : P Danke, @DigitalTrauma. BEARBEITEN: nachfolgende Zeilenumbrüche müssen berücksichtigt werden. Fügen Sie die Zeilenumbrüche hinzu und verwenden Sie die Absätze 1.
Addison Crump

11

Python 2, 32 Bytes

Am Ende der Datei befindet sich eine neue Zeile.

print open(__file__).readline()

Python 3, 33 Bytes

Am Ende der Datei befindet sich eine neue Zeile.

print(open(__file__).readline())

Dank feersum für das Auffangen eines Problems und das Bereitstellen von Informationen__file__ , Loovjo für einen neuen Ansatz für die Python 2-Lösung, mit der 17 Byte eingespart wurden, und Skyler für eine Lösung, mit der noch ein weiteres Byte eingespart wurde und die sowohl in Python 2 als auch in Python 3 printfunktioniert hat (anhängig , eine Funktion in Python zu sein) 3)!

Doku-Link für readline


Dies würde auch 2 Bytes in python3 einsparen, da Sie den endParameter verwerfen könnten .
Skyler

@Skyler Du hast absolut recht.
Celeo

Wie funktioniert das in Python 3, für das Parens benötigt werden print?
Türklinke

Auf Python 3 sollte print(open(__file__).readline())eine neue Zeile folgen.
Skyler

In Ihrem Python 3-Beispiel wird Python 2 anstelle von Python 3
TheInitializer

10

Stapel, 9 8 Bytes

@type %0

Ein Byte dank @Joshua gespeichert


3
Sie können ein Byte speichern, indem Sie das nachfolgende% entfernen.
Joshua

10

Python 2.7, 30 Bytes

print open(__file__).read(29)

Bearbeiten: Nur um klar zu sein, der obige Code soll am Ende eine neue Zeile als 30. Byte haben. Ich kenne Markdown nicht gut genug, um herauszufinden, wie es im Codeblock angezeigt wird.

Ich verwende hier den gleichen Trick wie in meiner C-Vorlage. Dadurch wird die gesamte Quelldatei mit Ausnahme der nachfolgenden Zeile gelesen, um den zusätzlichen Zeilenumbruch zu berücksichtigen, der printan die Ausgabe angehängt wird.


Stößt dies auf dasselbe Problem mit der nachgestellten Newline wie die andere Übermittlung?
Cole

Nein. Es soll eine nachgestellte Newline geben, die das 30. Byte im Quellcode enthält, aber ich kann nicht dafür sorgen, dass es im Codeblock angezeigt wird. Mein Beitrag funktioniert, weil er die ersten 29 Bytes des Quellcodes liest, damit der Zeilenumbruch printnicht überflüssig wird.
Xsot

4
Das macht das Komma nicht. Es wird ein Leerzeichen anstelle einer Newline angehängt.
XSOT

2
könnte ␤ verwenden, um eine semantisch wichtige neue Zeile anzugeben
Eevee

9

Java, 212 196 Bytes (171 Bytes mit fragwürdigen Hardcodierungsregeln)

Vielen Dank an @Cruncher für die Kürzung um ~ 15 Bytes!

Ich habe keinen Zweifel, dass dies Golf gespielt werden kann.

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

Oder eine andere Methode mit der statischen Methode (und dem Namen der Klasse), ich bekomme 171 Bytes. Ich bin mir jedoch nicht sicher, ob dies als fest codiert qualifiziert ist.

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

Verwendet einen Konstruktor, um den Klassennamen mit einer nicht statischen Methode abzurufen. Die Verwendung einer statischen Methode ( A.class.getName()) war wirklich hart codiert, daher habe ich die "richtige" Methode verwendet. Bei Verwendung von A.class.getName()wird dieser Code auf 171 Byte verkürzt.

Lesbare Versionen:

Konstruktor verwenden und 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) {}
    }
}

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

Erfasst alle Bytes der Datei auf einmal und gibt sie an STDOUT aus. Ziemlich einfach.


Warum einfach nicht benutzen A.class.getName()?
Fabio F.

3
Es ist CodeGolf, nicht CodeReview! ;)
Fabio F.

1
@FabioF. Ja, aber ich denke, das ist ein hartcodierter Dateiname, was gegen die Regeln verstößt. Der Punkt ist, wenn Sie den Namen der Datei ändern, müssen Sie den Namen der Klasse (offensichtlich) ändern, aber auch diese Zeile, die einem fest codierten Dateinamen ähnelt.
Cruncher

1
Können Sie die print-Anweisung nicht im Konstruktor aufrufen und sich das Setzen einer statischen Variablen ersparen?
Cruncher

1
@Cruncher Nah. Du bekommst java.io, ich bleibe bei java.nio - es geht nicht darum, zu gewinnen, sondern Wege aufzuzeigen, wie dies mit verschiedenen Methoden äußerst präzise gemacht werden kann.
Addison Crump

8

AutoIt, 34 Bytes

Gibt sich in die Zwischenablage aus:

ClipPut(FileRead(@ScriptFullPath))


7

Go, 111 105 Bytes

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

Mein erstes Code-Golf in Go - nur ein paar Tricks, die Sie hier anwenden können, denke ich.


In Go gibt es bereits eine Antwort. Verwendet diese Methode dieselbe?
Addison Crump

@VoteToClose: Mir ist klar, dass ich in der Tat von der anderen inspiriert war, aber hier die Umbenennung von Paketen (billiger Trick) sowie eine andere Technik zum Öffnen und Weiterleiten von Dateien an stdout verwendet habe. Hat mir gewaltige 22 Bytes gerettet
;-)

Die Methode ist eigentlich etwas anders, gut!
Fabian Schmengler

7

PowerShell, 39 36 31 25 Bytes

Etwa so eng wie ich es kriegen kann:

gc $MyInvocation.MyCommand.Path | oh

Aufgrund der großen Nachfrage wurde dies geändert in:

gc $PSCommandPath|echo -n

Druckt auf die aktuelle Standardausgabe der Host-Shell .


gc $MyInvocation.MyCommand.Pathreicht. Es wird automatisch ausgedruckt.
Andrew

Es ist nicht garantiert, insbesondere wenn das Skript im Hintergrund ausgeführt wird
Chad Baxter

Haha ja ist mir egal. Ich würde posten, wenn niemand eine PowerShell-Antwort hätte. Aber ich habe vergessen, dass dies gcein Alias ​​war und nur verwendet werden sollte cat, also hattest du sowieso ein Byte bei mir.
Andrew

Äh, ich wäre nicht so streng. Andernfalls müsste jede PS-Antwort explizit an die Host-Shell weitergeleitet werden, aber das liegt bei Ihnen ...
Andrew,

Sie könnten stattdessen gc $PSCommandPathfür 17 Bytes verwenden. Das Problem, das ich sehe, ist, dass dies eine neue Zeile ausspuckt (die in der Quelle nicht existiert). Es ist jetzt mehrdeutig, ob der Zeilenumbruch in Ordnung ist oder nicht ... je nachdem, wie diese Regeln lauten, müssen wir möglicherweise gc $PSCommandPath|write-host -nfür 31 Bytes etwas Kniffliges tun .
AdmBorkBork


5

C 49 Bytes

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

Bearbeiten: Zur Verdeutlichung ist das 49. Byte eine neue Zeile.

Dies liest den Quellcode abzüglich der Newline am Ende, um die Newline zu berücksichtigen puts, die am Ende der Ausgabe angehängt wird.


Dieser Code ruft zweimal undefiniertes Verhalten auf.
Joshua

5
Nun, das ist Codegolf. Mein Code erzeugt die gewünschte Ausgabe, sodass es sich um eine gültige Übermittlung handelt.
Xsot

1
@xsot In diesem Fall sollten Sie wahrscheinlich die Compiler-Version + -Optionen auflisten. Andernfalls ist dies möglicherweise nicht überprüfbar.
Justin

1
Wenn undefiniertes Verhalten zulässig ist, solange Sie einen Compiler haben, der in einer Mondphase auf einem Computer die gewünschte Ausgabe erzeugt, dann schlage ich int main (void) {* 0; } als Lösung. Schließlich würde der Standard eine Implementierung ermöglichen, die dies zu einem Programm kompiliert, das das Problem löst. Ich würde gut mit implementierungsabhängigem Verhalten umgehen können, solange Sie den Compiler angeben, aber mit undefiniertem Verhalten können Sie nicht einmal garantieren, dass Sie nicht zehn verschiedene Antworten erhalten, wenn Sie das zehn Mal hintereinander auf der Website ausführen gleiche Maschine.
Ray

1
@MDXF Ich habe nicht ernsthaft vorgeschlagen, diese Lösung zu schreiben. Ich habe mich dagegen ausgesprochen, undefiniertes Verhalten zuzulassen. funktioniert int main() {*0;} möglicherweise sogar auf vorhandenen Compilern, da sie undefiniertes Verhalten enthalten. In ähnlicher Weise xsot Lösung könnte auf bestehende Compiler arbeiten, da es nicht definiertes Verhalten enthält. Keiner von beiden ist garantiert, um das Problem zu lösen. (Obwohl xsot ist freilich mehr ist wahrscheinlich , dies zu tun, es könnte genauso einfach abstürzen). Mein eigentliches Argument ist, dass wir Lösungen zulassen sollten, die von implementierungsabhängigem oder nicht spezifiziertem Verhalten abhängen, aber nicht von undefiniertem Verhalten.
Ray


4

Pyth, 25 Bytes

$import sys$h'e$sys.argv

Dies liest seinen Dateinamen. Im Wesentlichen sucht es argv, öffnet die Datei, die dem letzten Argument entspricht, und gibt die erste Zeile aus.


Kannst du nicht einfach tun h'$__file__$?
kirbyfan64sos

@ kirbyfan64sos Das gibt mir den Fehler NameError: name '__file__' is not defined. Pyth wird in Python kompiliert und anschließend die resultierende Zeichenfolge ausgeführt. Ich würde also nicht erwarten, dass das funktioniert.
Isaacg

4

Los, 133 Bytes

Jeder klar? Gehen!

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

2
Dies hat mich dazu inspiriert, meine eigene (und die allererste) Code-Golf-Lösung in Go zu schreiben. Auf der Suche nach einigen allgemeinen Tricks können Sie hier leicht auf 123 Zeichen eingehen, indem Sie beispielsweise einzelne Buchstaben für Pakete verwenden r"runtime".
Tomasz

4

> <> , 13 Bytes

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

Getestet sowohl mit Online- als auch Offline-Dolmetschern. Der gBefehl kommt dem Lesen aus der Quelldatei am nächsten. Wenn er für diese Herausforderung nicht zählt, markiere ich meinen Eintrag als nicht konkurrierend. Ich glaube, es wird normalerweise als "Betrug" für Quines angesehen.

Probieren Sie es online aus.


4

Haskell, 63 Bytes

Für die Wissenschaft!

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

Funktioniert nur mit dem runhaskellBefehl. Sehr cool
HEGX64

4

> <> 31 Bytes

Haftungsausschluss: Es gibt keine Datei-E / A in> <>, ich fand es jedoch interessant, die von Befunge geerbten Codespace-E / A zu präsentieren, eine der Sprachen, die> <> inspiriert hat.

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

Eine selbstlesende Quine, die ich vor einiger Zeit gemacht habe, können Sie hier ausprobieren .

Ich habe gerade gesehen, dass es eine kürzere Quine gibt, die sich selbst liest . Während es in Code-Golf-Standards eindeutig besser ist, möchte ich darauf hinweisen, dass es eine fest codierte Codelänge hat, während meines zusätzliche Codezeilen oder -spalten kopieren würde (solange sie nicht den ursprünglichen Code brechen).


Ich habe überlegt, in> <>
Sp3000,

@ Sp3000 woops in der Tat, sieht so aus, als hätte ich die Herausforderung nicht gut genug gelesen. Ich werde einen Haftungsausschluss hinzufügen
Aaron

3

F #, 54 Bytes

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

Verwendungszweck:

fsi --exec a.fsx

3

Perl 5, 15 13 Bytes

Wir danken der Bash-Lösung, die dies inspiriert hat:

print`cat $0`

EDIT: Benötigen Sie nicht das Semikolon oder das erste Leerzeichen.


Nicht reines Perl, es braucht eine andere ausführbare Datei, nämlich catvorhanden und auffindbar in der $PATH. Wenn es jedoch vorhanden ist, kann es als nur ein Befehl angenommen werden, der verfügbar perlist. Warum also nicht?
Golar Ramblar

3

Node.js, 66 63 Bytes

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

console.logWird nicht verwendet , wodurch eine neue Zeile angehängt wird.


1
Sie können ein paar Bytes sparen, indem Sie die synchrone API verwenden:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike,

1
Warum nicht console.log(require('fs').readFileSync(process.argv[1]))\nfür 57 Bytes?
Conor O'Brien

Das funktioniert nicht immer. Angenommen, die Datei heißt test.js. Es ist gültig, es durch Ausführen aufzurufen node test, wodurch ein Fehler ausgelöst wird.
Patrick Roberts


3

Haskell , 49 Bytes

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

Probieren Sie es online!

(GHC) Haskell verfügt über eine Erweiterung für die Verwendung des C-Präprozessors (häufig für die Portabilität zwischen Versionen und Architekturen verwendet). Hoffentlich selbsterklärend.


3

HTML mit JavaScript, 115 Bytes (zählt nicht wirklich)

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

Zählt das? Es macht mir nichts aus, es hat Spaß gemacht :)

Technisch gesehen öffnet es keine Datei. Es ist auch ein wohlgeformtes HTML5-Dokument. Der XMLSerializer war das einzige Tool, das auch den DOCTYPE-Teil zurückgab, der jedoch nicht dem Standard entspricht. Trotzdem funktioniert es mit Chrome und Firefox, und ich wette, andere Browser.

Und als Bonus:

JavaScript, 41 Bytes

alert(document.currentScript.textContent)

Entfernen ";" Speichern Sie am Ende 1 Byte :)
Евгений Новиков

1
@ ЕвгенийНовиков Sie haben Recht, nicht sicher, warum ich das damals belassen habe. Es scheint, als hätte ich es nicht gezählt.
Domino
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.