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!

DerInitializer
quelle
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
Dennis
quelle
28
feline functionalities:)
theB
48

Bash, 6 Bytes

cat $0

Grundsätzlich gilt.

ein Spaghetto
quelle
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
Joshua
quelle
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.

Digitales Trauma
quelle
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
2
@kasperd Ja, garantiert von C89
Digital Trauma
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__).

Fabian Schmengler
quelle
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 !

Dom Hastings
quelle
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.

Hotkeys
quelle
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.

Addison Crump
quelle
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

Celeo
quelle
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

Fabian Schmengler
quelle
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.

xsot
quelle
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.

Addison Crump
quelle
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))
mınxomaτ
quelle
8

Rubin, 14

$>.<<IO.read$0
Histokrat
quelle
Nizza Verwendung von .Klammern zu vermeiden
Cyoce
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.

tomasz
quelle
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 .

Chad Baxter
quelle
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.

xsot
quelle
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
5

Mathematica, 16 Bytes

FilePrint@$Input

Führen Sie es im Skriptmodus aus .

Alephalpha
quelle
Ich benutze Mathematica seit vielen Jahren und hatte noch nie etwas über den Skriptmodus gehört.
Michael Stern
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.

isaacg
quelle
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))}
Fabian Schmengler
quelle
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.

cole
quelle
4

Haskell, 63 Bytes

Für die Wissenschaft!

import System.Environment
main=getProgName>>=readFile>>=putStr
Craig Roy
quelle
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).

Aaron
quelle
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
pswg
quelle
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.

Erikster
quelle
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.

Félix Saparelli
quelle
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

C 31 Bytes

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

Die Bash-Lösung ist so kurz, warum also nicht eine C-Lösung darauf aufbauen?

ugoren
quelle
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.

Ørjan Johansen
quelle
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)
Domino
quelle
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