Un quine "tricheur"


56

Lurker de longue date, première affiche. Alors voilà.

Dans la page Wikipedia de quine , il est indiqué que "une quine est considérée comme une" triche "si elle examine son propre code source". Votre tâche consiste à créer l’un de ces "quines de tricherie" qui lit son propre code source.

C'est du , donc le code le plus court en octets - dans chaque langue - gagne. Cela signifie qu'un script Pyth de 5 octets ne bat pas un script Python de 21 octets - mais un script Python de 15 octets.

Vous devez utiliser le fichier I / O pour lire le code source. Par conséquent, le code JavaScript suivant, extrait de la page officielle de Wikipedia, est invalide:

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

Il doit accéder au code source du fichier sur le disque .

Vous n'êtes pas autorisé à spécifier le nom du fichier. Vous devez lui faire détecter le nom du fichier lui-même.

Tout le monde est clair? Aller!


1
Les nouvelles lignes de fin ne sont-elles pas présentes dans le fichier d'origine?
isaacg

3
@isaacg IMHO Ce n'est pas une quine, car ce n'est pas le code source.
Mınxomaτ

3
Vous devez indiquer que le nom de fichier réel doit être déterminé au lieu d’assumer une chaîne codée en dur pour l’emplacement source.
Feersum

3
Je suis cependant d’accord avec @feersum, le fait de requérir un nom de fichier spécifique rend ce défi difficile.
mınxomaτ

1
Pouvons-nous supposer que (pour les langages compilés) le code source est dans le même dossier (nous pouvons simplement ajouter ".cpp" ou ".hs" à arg [0] pour obtenir le code source).
HEGX64

Réponses:


60

Zsh , 4 octets

<$0

Le shell Z intègre des fonctionnalités félines. Le quatrième caractère est un saut de ligne.

Essayez-le en ligne!

Le code ne dépend en aucun cas du nom du fichier; cela fonctionne même si le nom de fichier contient des caractères spéciaux, tels que des espaces ou des nouvelles lignes.

Essai

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

cat $0

Fondamentalement.


3
Il n’imprime pas de nouvelle ligne.
Addison Crump

2
catn’ajoute pas de nouvelle ligne (du moins sur mon système).
un spaghetto

7
@isaacg catimprime le contenu de l'octet de fichier fourni, octet par octet.
Dennis

2
@LukStorms Mais ne serait-ce pas une catsolution alors, au lieu d'une bashsolution? Et le chat n'est pas vraiment qualifié comme langage de programmation
Fabian Schmengler

30
Cela fonctionnera-t-il si le fichier est nommé -e?
Mark Plotnick

32

Chargeur exécutable UNIX, 10 octets

#!/bin/cat

Si le spam sur erreur standard ne vous intéresse pas, vous pouvez le raccourcir d'un octet:

#!/bin/dd

7
J'aime ça. Je ne sais pas si cela peut être qualifié de "langue".
Kevin

Peut-être tricher un peu, mais ne pourriez-vous pas renommer votre dossier bin et le programme cat pour raccourcir le chemin?
James Webster

3
Je ne suggère pas que vous faites . Je suggère que vous puissiez
James Webster

3
@ Kevin Le "langage" (c'est-à-dire l'interprète) est cat. Et je suppose que si vous voulez être très précis, un catprogramme s’imprime tout seul, et est compatible avec tous les formats de fichiers existants :)
l0b0

1
@ JamesWebster sudo install /bin/cat /c. Vous savez, juste au cas où /binn'est pas sur le système de fichiers racine. Je dois l'avoir catdans singleuser…
Blacklight Shining

25

C, 52

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

Bien sûr, ceci lit le code source et non le programme compilé - je suppose que cela correspond aux spécifications.


Vous pouvez utiliser printfau lieu de putspour éviter une fin de ligne.
Feersum

@feersum oui, bonne prise
Digital Trauma

19
@DigitalTrauma C'est à cause de votre avatar, bien sûr
Peter Olson

3
En fait, vous putspouvez utiliser readmoins de caractères.
user4098326


13

PHP, 21 octets

<?=file(__FILE__)[0];

filelit un fichier ligne par ligne dans un tableau et le fichier n'a qu'une seule ligne. Cela enregistre un octet par rapport à readfile(__FILE__).


Notez que cela ne fonctionne qu'à partir de PHP 5.4 et plus récent, qui était la première version à prendre en charge la déférentiation des tableaux. Mais à part ça, c'est une bonne réponse!
Ismael Miguel

1
readfileest également 21: <?readfile(__FILE__);.
Primo

1
Bon, ça ne sert à rien<?=
Fabian Schmengler

12

Perl, 15 octets

open 0;print<0>

Sauvegardé 3 octets grâce à @ ThisSuitIsBlackNot !


2
Vous pouvez économiser 3 octets avecopen 0;print<0>
ThisSuitIsBlackNot

@ThisSuitIsBlackNot J'étais sûr qu'il y avait un moyen plus court de le faire, mais je ne pouvais pas le faire pour la vie de mon travail ... L'utilisation 0suppose $0alors?
Dom Hastings

3
Oui. Voir perldoc -f open: "En tant que raccourci, un appel à un argument prend le nom de fichier de la variable scalaire globale du même nom que le $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";
descripteur de fichier

11

Perl 6, 20 octets

print slurp $?FILE

Je n'ai pas travaillé longtemps avec Perl 6, donc je ne suis pas sûr qu'il existe des astuces pour le rendre plus court.


2
pouvez-vous supprimer le deuxième espace?
Eevee

3
@Evee Nope, il se met en colère
Touches

11

osascript (AppleScript depuis la ligne de commande), 40 33 32 octets

(Lire le chemin vers moi) paragraphe 1

Exécuter sur un fichier appelé avec osascript a.

Obtient le premier paragraphe (ligne) du fichier et l'imprime dans STDOUT avec une nouvelle ligne, ainsi que la nouvelle ligne dans le code.


1
Voir mon édition à l'OP
TheInitializer

Travailler à le faire fonctionner.
Addison Crump

read path to mesemble fonctionner pour moi. El Cap.
Digital Trauma

Je n'ai pas vu ça, mais c'est comme ça que j'ai fini par le faire. : P Merci, @ DigitalTrauma. EDIT: les nouvelles lignes finales doivent être prises en compte, vous devez donc ajouter la nouvelle ligne et utiliser les paragraphes 1.
Addison Crump

11

Python 2, 32 octets

Il y a une nouvelle ligne à la fin du fichier.

print open(__file__).readline()

Python 3, 33 octets

Il y a une nouvelle ligne à la fin du fichier.

print(open(__file__).readline())

Merci à feersum d’ avoir attrapé un problème et d’avoir fourni __file__, Loovjo pour une nouvelle approche de la solution Python 2 qui économise 17 octets, et Skyler pour une solution qui enregistrait un autre octet et fonctionnait à la fois en Python 2 et 3 (en attente d’ printêtre une fonction dans Python). 3)!

Lien Doc pour readline


Cela économiserait également 2 octets dans python3 car vous pourriez supprimer le endparamètre.
Skyler

@ Skyler Vous avez absolument raison.
Celeo

Comment cela fonctionne-t-il dans Python 3, qui a besoin de parens print?
Poignée de porte

Python 3 devrait être print(open(__file__).readline())suivi d'une nouvelle ligne.
Skyler

Votre exemple avec Python 3 indique Python 2 plutôt que Python 3
TheInitializer

10

Lot, 9 8 octets

@type %0

Enregistré un octet grâce à @Joshua


3
Vous pouvez enregistrer un octet en éliminant le% de fin.
Josué

10

Python 2.7, 30 octets

print open(__file__).read(29)

Edit: Juste pour être clair, le code ci-dessus est supposé avoir une nouvelle ligne à la fin du 30ème octet. Je ne suis pas assez familiarisé avec le démarquage pour savoir comment l'afficher dans le bloc de code.

J'utilise le même truc ici que celui de ma soumission en C. Ceci lit l'intégralité du fichier source, à l'exclusion de la nouvelle ligne de fin, afin de prendre en compte la nouvelle ligne qui printsera ajoutée à la sortie.


Cela pose-t-il le même problème avec la nouvelle ligne de fuite que l'autre soumission?
Cole

Non. Il est supposé être un retour à la ligne final qui crée le 30e octet dans le code source, mais je ne parviens pas à l'afficher dans le bloc de code. Ma soumission fonctionne parce qu'elle lit les 29 premiers octets du code source afin que la nouvelle ligne de printne soit pas étrangère.
xsot

4
Ce n'est pas ce que fait la virgule. Il ajoute un espace au lieu d'une nouvelle ligne.
xsot

2
pourrait utiliser ␤ pour indiquer un saut de ligne sémantiquement important
Eevee

9

Java, 212 196 octets (171 octets avec des règles de codage en dur douteuses)

Merci à @Cruncher pour le raccourcir de ~ 15 octets!

Je ne doute pas que cela peut être joué au 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){}}}

Ou, une autre méthode, en utilisant la méthode statique (et le nom de la classe), je reçois 171 octets. Je ne sais pas si cela est qualifié de codé en dur, cependant.

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

Utilise un constructeur pour obtenir le nom de la classe par une méthode non statique. Utiliser une méthode statique ( A.class.getName()) était très difficile à coder, alors j’ai utilisé la méthode «correcte». En utilisant A.class.getName(), ce code est réduit à 171 octets.

Versions lisibles:

Utiliser constructeur et 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) {}
    }
}

En utilisant la méthode statique 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"))));
    }
}

Récupère tous les octets du fichier à la fois et les envoie à STDOUT. Assez simple.


Pourquoi ne pas utiliser A.class.getName()?
Fabio F.

3
C'est CodeGolf pas CodeReview! ;)
Fabio F.

1
@FabioF. Oui, mais je pense que cela ressemble à un nom de fichier codé en dur, ce qui est contraire aux règles. Le fait est que si vous modifiez le nom du fichier, vous devez modifier le nom de la classe (évidemment), mais également modifier cette ligne, qui ressemble à un nom de fichier codé en dur.
Cruncher

1
Ne pouvez-vous pas appeler l'instruction print dans le constructeur et éviter de définir une variable statique?
Cruncher

1
@ Cruncher Nah. Vous obtenez java.io, je vais m'en tenir à java.nio - le but n'est pas de gagner, mais de montrer des façons de le faire de manière très concise avec différentes méthodes.
Addison Crump

8

AutoIt, 34 octets

Se produit dans le presse-papier:

ClipPut(FileRead(@ScriptFullPath))


7

Go, 111 à 105 octets

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

Mon premier code-golf dans Go - quelques astuces que vous pouvez utiliser ici, je suppose.


Il y a déjà une réponse dans Go - cela utilise-t-il la même méthode?
Addison Crump

@VoteToClose: Je m'en rends bien compte, j'ai été inspiré par l'autre, mais j'ai utilisé le renommage de paquet utilisé ici (astuce économique) ainsi que différentes techniques pour ouvrir un fichier de passe-passe sur stdout.
M'a

La méthode est en fait un peu différente, bonne!
Fabian Schmengler

7

PowerShell, 39 36 31 25 octets

À peu près aussi serré que je peux l'obtenir:

gc $MyInvocation.MyCommand.Path | oh

Soutenu par la demande populaire, cela a été changé en:

gc $PSCommandPath|echo -n

imprime vers la sortie standard actuelle du shell shell .


gc $MyInvocation.MyCommand.Pathest assez. Il sera automatiquement imprimé.
Andrew

ce n'est pas garanti, surtout si le script tourne silencieusement
Chad Baxter

Haha oui je m'en fiche. J'allais poster si personne d'autre n'avait de réponse à PowerShell. Mais j'ai oublié que gcc'était un pseudonyme et que nous allions l'utiliser cat, alors vous aviez un octet sur moi de toute façon.
Andrew

Euh, je ne serais pas si strict à ce sujet. Sinon, chaque réponse du PS devra explicitement se connecter au shell de l'hôte, mais c'est à vous de décider ...
Andrew

Vous pouvez utiliser gc $PSCommandPathà la place 17 octets. Le problème que je vois est que cela crache une nouvelle ligne (qui n'existe pas dans le source). C’est ambigu maintenant si le retour à la ligne est correct ou non. En fonction de la façon dont les règles sont définies, nous devrons peut-être faire quelque chose de très délicat comme gc $PSCommandPath|write-host -n31 octets.
AdmBorkBork


5

C, 49 octets

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

Edit: Pour clarifier, le 49ème octet est une nouvelle ligne.

Ceci lit le code source moins la nouvelle ligne à la fin pour prendre en compte la nouvelle ligne qui putssera ajoutée à la fin de la sortie.


Ce code appelle le comportement indéfini deux fois.
Josué

5
Eh bien, c'est du code golf. Mon code produit la sortie souhaitée, donc c'est une soumission valide.
xsot

1
@xsot Dans ce cas, vous devriez probablement lister la version du compilateur + les options; sinon, cela pourrait ne pas être vérifiable.
Justin

1
Si le comportement indéfini est autorisé tant que vous pouvez avoir un compilateur qui produit la sortie souhaitée sur une machine pendant une phase de la lune, alors je propose int main (void) {* 0; } comme solution. Après tout, la norme permettrait une implémentation qui compilerait cela dans un programme qui résoudrait le problème. J'utiliserais bien le comportement dépendant de l'implémentation tant que vous spécifiez le compilateur, mais avec un comportement indéfini, vous ne pouvez même pas garantir que vous n'obtiendrez pas dix réponses différentes si vous l'exécutiez dix fois de suite sur même machine.
Ray

1
@ MDXF Je ne proposais pas sérieusement d'écrire cette solution. Je discutais contre le fait de permettre un comportement indéfini. int main() {*0;} peut fonctionner même sur des compilateurs existants, car il contient un comportement indéfini. De même, la solution de xsot pourrait fonctionner sur des compilateurs existants, car elle contient un comportement indéfini. Aucun des deux n'est garanti pour résoudre le problème. (Bien que xsot soit sans doute plus susceptible de le faire, il pourrait tout aussi bien s’effondrer). Mon argument actuel est que nous devrions autoriser les solutions qui dépendent d'un comportement dépendant de l'implémentation ou non spécifié, mais pas d'un comportement indéfini.
Ray


4

Pyth, 25 octets

$import sys$h'e$sys.argv

Ceci lit son nom de fichier. Essentiellement, il recherche argv, ouvre le fichier correspondant à son dernier argument et affiche sa première ligne.


Tu ne peux pas faire juste h'$__file__$?
Kirbyfan64sos

@ kirbyfan64sos Cela me donne l'erreur NameError: name '__file__' is not defined. Pyth est compilé en Python, puis la chaîne résultante est exécutée. Donc, je ne m'attendrais pas à ce que cela fonctionne.
isaacg

4

Go, 133 octets

Tout le monde est clair? Aller!

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

2
Cela m'a inspiré pour écrire ma propre (et la toute première) solution code-golf dans Go. En cherchant quelques astuces générales, vous pouvez facilement descendre à 123 caractères en appliquant des noms d'une seule lettre pour les packages, par exemple r"runtime".
Tomasz

4

> <> , 13 octets

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

Testé à la fois sur les interprètes en ligne et hors ligne. La gcommande est la plus proche de la capacité de lire à partir du fichier source et si elle ne compte pas pour le but de ce défi, je marquerai mon entrée comme non compétitive; Je crois que c'est normalement considéré comme "tricher" pour les quines.

Essayez-le en ligne.


4

Haskell, 63 octets

Pour la science!

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

Fonctionne uniquement avec la runhaskellcommande. Très cool cependant
HEGX64

4

> <> , 31 octets

Avertissement: il n'y a pas de fichier d'E / S dans> <>, mais j'ai pensé qu'il serait intéressant de présenter ses E / S d'espace de code héritées de Befunge, l'un des langages ayant inspiré> <>.

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

Une Quine auto-lisante que j'ai faite il y a quelque temps, vous pouvez l'essayer ici .

Je viens de voir qu'il y a un > plus> quine auto-lecture plus court . Bien que cela soit clairement meilleur dans les standards de code-golf, je voudrais souligner qu'il a une longueur de code codée en dur, tandis que le mien copierait des lignes ou des colonnes de code supplémentaires (tant qu'elles ne cassent pas le code original).


Je pensais publier dans> <>, mais je pensais que> <> serait impossible en raison de la règle suivante: "Vous devez utiliser le fichier E / S pour lire le code source"
Sp3000

@ Sp3000 woops en effet, on dirait que je n'ai pas assez lu le défi. Je vais ajouter une clause de non
Aaron

3

F #, 54 octets

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

Usage:

fsi --exec a.fsx

3

Perl 5, 15 13 octets

Le mérite de la solution Bash pour avoir inspiré ceci:

print`cat $0`

EDIT: Pas besoin du point-virgule ou du premier espace.


Non pur perl, il a besoin d’un autre exécutable, à savoir cat, présent et trouvable dans le répertoire $PATH. Mais si elle est présente, elle peut être considérée comme une simple commande accessible perl, alors pourquoi pas.
Golar Ramblar

3

Node.js, 66 63 octets

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

N'utilise pas console.log, ce qui ajoute une nouvelle ligne.


1
Vous pouvez économiser quelques octets en utilisant l’API synchrone:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike

1
Pourquoi pas console.log(require('fs').readFileSync(process.argv[1]))\npour 57 octets?
Conor O'Brien

Cela ne marche pas toujours. Dites que le fichier est nommé test.js. Il est valide de l'invoquer en exécutant node test, ce qui provoquera une erreur.
Patrick Roberts

3

C, 31 octets

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

La solution bash est si courte, alors pourquoi ne pas utiliser une solution C dessus?


3

Haskell , 49 octets

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

Essayez-le en ligne!

(GHC) Haskell a une extension pour utiliser le préprocesseur C (couramment utilisé pour la portabilité entre les versions et les architectures).


3

HTML avec JavaScript, 115 octets (ne compte pas vraiment)

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

Est-ce que ça compte? Ça ne me dérange pas, c'était amusant :)

Techniquement, il n’ouvre pas de fichier. C'est aussi un document HTML5 bien formé. XMLSerializer était le seul outil qui renvoyait également la partie DOCTYPE, mais qui n'était pas standard. Pourtant, cela fonctionne sur Chrome et Firefox, et je parie que les autres navigateurs.

Et en bonus:

JavaScript, 41 octets

alert(document.currentScript.textContent)

Retirer ";" à la fin, économisez 1 octet :)
вгений Новиков

1
@ ЕвгенийНовиков Vous avez raison, je ne sais pas pourquoi j'ai laissé cela à l'époque. Il semble que je ne l'ai pas compté cependant.
Domino
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.