Una quine "trampa"


56

Acechador desde hace mucho tiempo, cartel por primera vez. Entonces aquí va.

En la página de Wikipedia para quine , dice que "una quine se considera 'trampa' si mira su propio código fuente". Su tarea es hacer una de estas "trampas" que lea su propio código fuente.

Este es el , por lo que gana el código más corto en bytes, en cada idioma . Esto significa que un script Pyth de 5 bytes no superaría a un script Python de 21 bytes, pero un script Python de 15 bytes sí.

Debe usar la E / S de archivo para leer el código fuente, por lo que el siguiente código JavaScript, tomado de la página oficial de Wikipedia, no es válido:

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

Debe acceder al código fuente del archivo en el disco .

No tiene permiso para especificar el nombre del archivo. Debe hacer que detecte el nombre del archivo en sí.

¿Todo el mundo claro? ¡Ir!


1
¿Están permitidas las nuevas líneas finales no presentes en el archivo original?
isaacg

3
@isaacg En mi humilde opinión Eso no es una quine, ya que no es el código fuente.
mınxomaτ

3
Debe indicar el requisito de que determine el nombre de archivo real en lugar de asumir una cadena codificada para la ubicación de origen.
feersum

3
Sin embargo, estoy de acuerdo con @feersum, que requerir un nombre de archivo específico hace que este desafío sea trivial.
mınxomaτ

1
Podemos suponer que (para los idiomas compilados) el código fuente está en la misma carpeta (es decir, simplemente podemos agregar ".cpp" o ".hs" a arg [0] para obtener la fuente).
HEGX64

Respuestas:


60

Zsh , 4 bytes

<$0

El caparazón Z tiene funcionalidades felinas integradas. El cuarto personaje es un salto de línea.

Pruébalo en línea!

El código no depende de ninguna manera del nombre del archivo; funciona incluso si el nombre del archivo contiene caracteres especiales, como espacios o líneas nuevas.

Prueba de funcionamiento

$ 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

Básicamente.


3
No imprime una nueva línea.
Addison Crump

2
catno agrega una nueva línea (al menos en mi sistema).
un spaghetto

77
@isaacg catimprime el contenido del archivo proporcionado byte por byte.
Dennis

2
@LukStorms Pero, ¿no sería una catsolución entonces, en lugar de una bashsolución? Y cat realmente no califica como lenguaje de programación
Fabian Schmengler

30
¿Funcionará esto si se nombra el archivo -e?
Mark Plotnick

32

Cargador ejecutable UNIX, 10 bytes

#!/bin/cat

Si no le importa el spam en el error estándar, puede hacerlo un byte más corto:

#!/bin/dd

77
Me gusta esto. Sin embargo, no estoy seguro de si califica como un "idioma".
Kevin

Quizás haciendo trampa un poco, pero ¿no podría cambiar el nombre de su carpeta bin y el programa cat para acortar el camino?
James Webster

3
No estoy sugiriendo que lo hace por cierto. Estoy sugiriendo que podía
James Webster

3
@Kevin El "lenguaje" (es decir, intérprete) es cat. Y supongo que si quieres ser muy específico, un catprograma simplemente se imprime solo y es compatible con todos los formatos de archivo existentes :)
l0b0

1
@JamesWebster sudo install /bin/cat /c. Ya sabes, por si acaso /binno está en el sistema de archivos raíz. Tengo que tener eso caten un solo usuario ...
Blacklight Shining

25

C, 52

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

Por supuesto, esto lee el código fuente y no el programa compilado, supongo que está dentro de las especificaciones.


Puede usar en printflugar de putsevitar una nueva línea final.
feersum

@feersum sí, buena captura
Digital Trauma

19
@DigitalTrauma Es por tu avatar, por supuesto
Peter Olson

3
En realidad, putsse puede usar, solo necesita readmenos caracteres.
user4098326


13

PHP, 21 bytes

<?=file(__FILE__)[0];

filelee un archivo línea por línea en una matriz y el archivo solo tiene una línea. Esto ahorra un byte en comparación con readfile(__FILE__).


Tenga en cuenta que esto solo funciona desde PHP5.4 y versiones posteriores, que fue la primera versión que admitió la desreferenciación de matrices. Pero aparte de eso, ¡una buena respuesta!
Ismael Miguel

1
readfilees también 21: <?readfile(__FILE__);.
primo

1
Correcto, no es necesario<?=
Fabian Schmengler 03 de

12

Perl, 15 bytes

open 0;print<0>

¡Guardado 3 bytes gracias a @ ThisSuitIsBlackNot !


2
Puede guardar 3 bytes conopen 0;print<0>
ThisSuitIsBlackNot

@ThisSuitIsBlackNot Estaba seguro de que había una forma más corta de hacerlo, pero no pude por la vida de mi trabajo ... ¿Usando 0supuestos $0entonces?
Dom Hastings

3
Sí. Consulte perldoc -f open: "Como acceso directo, una llamada de un argumento toma el nombre de archivo de la variable escalar global del mismo nombre que el $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";
identificador de archivo

11

Perl 6, 20 bytes

print slurp $?FILE

No he trabajado con Perl 6 por mucho tiempo, así que no estoy seguro de si hay algún truco para hacerlo más corto.


2
puedes quitar el segundo espacio?
Eevee

3
@ Evee no, se enoja
Hotkeys

11

osascript (AppleScript desde la línea de comando), 40 33 32 bytes

(lee el camino hacia mí) el párrafo 1

Ejecutando en un archivo llamado a con osascript a.

Obtiene el primer párrafo (línea) del archivo y lo imprime en STDOUT con una nueva línea final, por lo tanto, la nueva línea en el código.


1
Vea mi edición en el OP
TheInitializer

Trabajando para que funcione.
Addison Crump

read path to meParece funcionar para mi. El Cap.
Trauma digital

No vi esto, pero así es como terminé haciéndolo. : P Gracias, @DigitalTrauma. EDITAR: las nuevas líneas finales deben considerarse, por lo que debe agregar la nueva línea y usar los párrafos 1.
Addison Crump

11

Python 2, 32 bytes

Hay una nueva línea al final del archivo.

print open(__file__).readline()

Python 3, 33 bytes

Hay una nueva línea al final del archivo.

print(open(__file__).readline())

Gracias a feersum por detectar un problema y suministrarlo __file__, Loovjo por un nuevo enfoque de la solución Python 2 que ahorró 17 bytes, y Skyler por una solución que ahorró otro byte y funcionó tanto en Python 2 como en 3 (pendiente de printser una función en Python 3)!

Enlace de documento para readline


Esto también ahorraría 2 bytes en python3 porque podría descartar el endparámetro.
Skyler

@Skyler Tienes toda la razón.
Celeo

¿Cómo funciona esto en Python 3, que necesita parens print?
Pomo de la puerta

Python 3 debe ir print(open(__file__).readline())seguido de una nueva línea.
Skyler

Su ejemplo de Python 3 dice Python 2 en lugar de Python 3
TheInitializer


10

Python 2.7, 30 bytes

print open(__file__).read(29)

Editar: solo para ser claros, se supone que el código anterior tiene una nueva línea al final como el byte 30. No estoy familiarizado con Markdown lo suficiente como para descubrir cómo mostrarlo en el bloque de código.

Estoy usando el mismo truco aquí que el de mi presentación en C. Esto lee todo el archivo fuente, excluyendo la nueva línea final para dar cuenta de la nueva línea adicional que se printagregará a la salida.


¿Esto se encuentra con el mismo problema con la nueva línea final que la otra presentación?
cole

No. Se supone que hay una nueva línea final que hace el byte 30 en el código fuente, pero no puedo hacer que se muestre en el bloque de código. Mi envío funciona porque lee los primeros 29 bytes del código fuente para que la nueva línea printno sea extraña.
xsot

44
Eso no es lo que hace la coma. Agrega un espacio en lugar de una nueva línea.
xsot

2
podría usar ␤ para indicar una nueva línea semánticamente importante
Eevee

9

Java, 212 196 bytes (171 bytes con reglas de codificación duros cuestionables)

¡Gracias a @Cruncher por acortarlo en ~ 15 bytes!

No tengo dudas de que esto se puede jugar al 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){}}}

O, otro método, usando el método estático (y el nombre de la clase), obtengo 171 bytes. Sin embargo, no estoy seguro de si esto califica como codificado.

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

Utiliza un constructor para obtener el nombre de la clase mediante un método no estático. El uso de un método estático ( A.class.getName()) estaba realmente codificado, así que utilicé la forma 'adecuada'. Usando A.class.getName(), este código se acorta a 171 bytes.

Versiones legibles:

Usando constructor y 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) {}
    }
}

Usando el método estático 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"))));
    }
}

Toma todos los bytes del archivo a la vez y lo envía a STDOUT. Muy claro.


¿Por qué simplemente no usar A.class.getName()?
Fabio F.

3
¡Es CodeGolf, no CodeReview! ;)
Fabio F.

1
@FabioF. Sí, pero creo que baila en la línea de ser un nombre de archivo codificado, lo que va en contra de las reglas. El punto es que si cambia el nombre del archivo, debe cambiar el nombre de la clase (obviamente), pero también cambiar esta línea, que es como un nombre de archivo codificado.
Cruncher

1
¿No puede llamar a la declaración de impresión dentro del constructor y ahorrarse de establecer una variable estática?
Cruncher

1
@Cruncher Nah. Obtienes java.io, me quedaré con java.nio: el punto no es ganar, sino mostrar formas de hacerlo de manera extremadamente concisa con diferentes métodos.
Addison Crump

8

AutoIt, 34 bytes

Se envía al portapapeles:

ClipPut(FileRead(@ScriptFullPath))


7

Ir, 111105 bytes

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

Mi primer código de golf en Go: supongo que solo algunos trucos que puedes usar aquí.


Ya hay una respuesta en Go: ¿utiliza esto el mismo método?
Addison Crump

@VoteToClose: Me doy cuenta, me inspiró el otro, pero usé el cambio de nombre del paquete aquí (truco barato), así como diferentes técnicas para abrir y canalizar archivos a stdout. Me ahorró un enorme 22 bytes ;-)
tomasz

El método es en realidad un poco diferente, ¡bueno!
Fabian Schmengler

7

PowerShell, 39 36 31 25 Bytes

Tan apretado como puedo conseguirlo:

gc $MyInvocation.MyCommand.Path | oh

Respaldado por la demanda popular, esto se ha cambiado a:

gc $PSCommandPath|echo -n

imprime en la salida estándar actual del shell del host .


gc $MyInvocation.MyCommand.Pathes suficiente. Lo imprimirá automáticamente.
Andrew

no está garantizado especialmente si el script se ejecuta en silencio
Chad Baxter

Jaja sí no me importa. Iba a publicar si nadie más tenía una respuesta de PowerShell. Pero olvidé que gcera un alias y que solo iba a usar cat, así que tenías un byte allí de todos modos.
Andrew

No sería tan estricto al respecto. De lo contrario, cada respuesta de PS tendría que canalizarse explícitamente al shell del host, pero eso depende de usted ...
Andrew

En su lugar, podría usar gc $PSCommandPathpara 17 bytes. El problema que veo es que esto escupe una nueva línea (que no existe en la fuente). Es ambiguo ahora si la nueva línea final está bien o no ... dependiendo de cómo eso rige, es posible que tengamos que hacer algo engañoso gc $PSCommandPath|write-host -npara 31 bytes.
AdmBorkBork


5

C, 49 bytes

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

Editar: para aclarar, el byte 49 es una nueva línea.

Esto lee el código fuente menos la nueva línea al final para dar cuenta de la nueva línea que se putsagregará al final de la salida.


Este código invoca un comportamiento indefinido dos veces.
Joshua

55
Bueno, este es el código de golf. Mi código produce el resultado deseado, por lo que es un envío válido.
xsot

1
@xsot En ese caso, probablemente debería enumerar la versión del compilador + opciones; de lo contrario, esto podría no ser verificable.
Justin

1
Si se permite un comportamiento indefinido siempre que pueda tener algún compilador que produzca la salida deseada en alguna máquina durante alguna fase de la luna, entonces propongo int main (void) {* 0; } como una solución. Después de todo, el estándar permitiría una implementación que compila eso en un programa que resuelva el problema. Estaría bien con el uso de un comportamiento dependiente de la implementación siempre que especifique el compilador, pero con un comportamiento indefinido, ni siquiera puede garantizar que no obtendrá diez respuestas diferentes si ejecuta diez veces seguidas en el misma máquina
Ray

1
@ MDXF No estaba sugiriendo seriamente que escribiéramos esa solución. Estaba argumentando en contra de permitir un comportamiento indefinido. int main() {*0;} podría funcionar incluso en compiladores existentes, ya que contiene un comportamiento indefinido. Del mismo modo, la solución de xsot podría funcionar en compiladores existentes, ya que contiene un comportamiento indefinido. Ninguno de los dos tiene la garantía de resolver el problema. (Aunque es probable que xsot sea más probable que lo haga, podría bloquearse con la misma facilidad). Mi argumento real es que debemos permitir soluciones que dependan de un comportamiento no especificado o dependiente de la implementación, pero no de un comportamiento indefinido.
Rayo


4

Pyth, 25 bytes

$import sys$h'e$sys.argv

Esto lee su nombre de archivo. Básicamente, busca argv, abre el archivo correspondiente a su último argumento e imprime su primera línea.


¿No puedes simplemente hacer h'$__file__$?
kirbyfan64sos

@ kirbyfan64sos Eso me da el error NameError: name '__file__' is not defined. Pyth se compila en Python, y luego se ejecuta la cadena resultante. Así que no esperaría que eso funcione.
isaacg

4

Ir, 133 bytes

¿Todo el mundo claro? ¡Ir!

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

2
Esto me inspiró a escribir mi propia (y la primera) solución de código de golf en Go. Buscando algunos trucos generales, puede bajar fácilmente a 123 caracteres aquí aplicando nombres de una sola letra para los paquetes, por ejemplo r"runtime".
tomasz

4

> <> , 13 bytes

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

Probado tanto en intérpretes en línea como fuera de línea. El gcomando es el más cercano a poder leer desde el archivo fuente y si no cuenta para el propósito de este desafío, marcaré mi entrada como no competitiva; Creo que normalmente se considera "trampa" para quines.

Pruébalo en línea.


4

Haskell, 63 bytes

¡Para la ciencia!

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

Solo funciona con el runhaskellcomando. Sin embargo
HEGX64

4

> <> , 31 bytes

Descargo de responsabilidad: no hay E / S de archivo en> <>, sin embargo, pensé que sería interesante mostrar su E / S de espacio de código heredado de Befunge, uno de los idiomas que inspiró> <>.

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

Un Quine de auto lectura que hice hace algún tiempo, puedes probarlo aquí .

Acabo de ver que hay una quine de lectura más corta> <> . Si bien es claramente mejor en los estándares de código de golf, me gustaría señalar que tiene una longitud de código codificada, mientras que la mía copiaría líneas o columnas de código adicionales (siempre que no rompan el código original).


Estaba pensando en publicar en> <>, pero pensé que> <> sería imposible debido a la regla: "Debe usar E / S de archivo para leer el código fuente"
Sp3000

@ Sp3000 woops de hecho, parece que no leí el desafío lo suficientemente bien. Agregaré un descargo de responsabilidad
Aaron

3

F #, 54 bytes

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

Uso:

fsi --exec a.fsx

3

Perl 5, 15 13 bytes

Crédito a la solución Bash por inspirar esto:

print`cat $0`

EDITAR: No necesita el punto y coma ni el primer espacio.


No es puro perl, necesita algún otro ejecutable, a saber cat, presente y encontrable en el $PATH. Pero si está presente, se puede suponer como un comando disponible perl, entonces, ¿por qué no?
Golar Ramblar

3

Node.js, 66 63 bytes

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

No usa console.log, que agrega una nueva línea.


1
Puede guardar algunos bytes utilizando la API síncrona:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike

1
¿Por qué no console.log(require('fs').readFileSync(process.argv[1]))\npara 57 bytes?
Conor O'Brien

Esto no siempre funciona. Digamos que el archivo se llama test.js. Es válido invocarlo ejecutando node test, lo que hará que esto arroje un error.
Patrick Roberts el


3

Haskell , 49 bytes

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

Pruébalo en línea!

(GHC) Haskell tiene una extensión para usar el preprocesador C (comúnmente utilizado para la portabilidad entre versiones y arquitecturas). Esperemos que se explique por sí mismo.


3

HTML con JavaScript, 115 bytes (realmente no cuenta)

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

¿Esto cuenta? No me importa, fue divertido :)

Técnicamente no abre un archivo. También es un documento HTML5 bien formado. XMLSerializer fue la única herramienta que también devolvió la parte DOCTYPE, pero no es estándar. Aún así, funciona en Chrome y Firefox, y apuesto a otros navegadores.

Y como extra:

JavaScript, 41 bytes

alert(document.currentScript.textContent)

Eliminar ";" al final, guarde 1 byte :)
Евгений Новиков

1
@ ЕвгенийНовиков Tienes razón, no estoy seguro de por qué lo dejé en ese entonces. Sin embargo, parece que no lo conté.
Domino
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.