Um quine "trapaceiro"

56

Observador veterano, postador iniciante. Então aqui vai.

Na página da Wikipedia para quine , ele diz que "um quine é considerado 'trapaceiro' se observar seu próprio código-fonte". Sua tarefa é criar um desses "truques" que lê seu próprio código-fonte.

Isso é , então o código mais curto em bytes - em cada idioma - vence. Isso significa que um script Pyth de 5 bytes não superaria um script Python de 21 bytes - mas um script Python de 15 bytes.

Você deve usar a E / S do arquivo para ler o código-fonte, para que o seguinte código JavaScript, retirado da página oficial da Wikipedia, seja inválido:

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

Ele deve acessar o código fonte do arquivo no disco .

Você não tem permissão para especificar o nome do arquivo. Você deve fazê-lo detectar o próprio nome do arquivo.

Todo mundo está limpo? Ir!

TheInitializer
fonte
11
É permitida uma nova linha à direita no arquivo original?
Isaacg
3
@isaacg IMHO Isso não é um problema, pois não é o código fonte.
mınxomaτ 29/10/2015
3
Você deve declarar um requisito para determinar o nome do arquivo real em vez de assumir uma string codificada para o local de origem.
feersum
3
No entanto, concordo com @feersum, que exigir um nome de arquivo específico torna esse desafio um caminho trivial.
mınxomaτ 29/10/2015
11
Podemos supor que (para idiomas compilados) o código fonte esteja na mesma pasta (ou seja, podemos apenas adicionar ".cpp" ou ".hs" a arg [0] para obter o código-fonte).
HEGX64

Respostas:

60

Zsh , 4 bytes

<$0

O shell Z possui funcionalidades felinas incorporadas. O quarto caractere é um avanço de linha.

Experimente online!

O código não depende de forma alguma do nome do arquivo; funciona mesmo que o nome do arquivo contenha caracteres especiais, como espaços ou novas linhas.

Execução de teste

$ 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
fonte
28
feline functionalities:)
theB
48

Bash, 6 bytes

cat $0

Basicamente.

um spaghetto
fonte
3
Não imprime uma nova linha.
Addison Crump
2
catnão anexa uma nova linha (pelo menos no meu sistema).
um Spaghetto
7
@isaacg catimprime o conteúdo do arquivo fornecido byte por byte.
Dennis
2
@LukStorms Mas isso não seria uma catsolução, em vez de uma bashsolução? E gato realmente não qualificar como linguagem de programação
Fabian Schmengler
30
Isso funcionará se o arquivo for nomeado -e?
precisa
32

Carregador executável UNIX, 10 bytes

#!/bin/cat

Se você não se importa com spam em erro padrão, pode reduzi-lo em um byte:

#!/bin/dd
Joshua
fonte
7
Eu gosto disso. Não tenho certeza se ele se qualifica como um "idioma".
21415 Kevin
Talvez trapaceando um pouco, mas você não pode renomear sua pasta bin e o programa cat para encurtar o caminho?
James Webster
3
Não estou sugerindo que você faça o mesmo . Estou sugerindo que você poderia
James Webster
3
@ Kevin A "linguagem" (isto é, intérprete) é cat. E eu acho que se você quer ser muito específico, um catprograma simplesmente imprime em si, e é compatível com todos os formatos de arquivo na existência :)
l0b0
11
@JamesWebster sudo install /bin/cat /c. Você sabe, apenas no caso de /binnão estar no sistema de arquivos raiz. Tenho que ter isso catem um único usuário ...
Blacklight Shining
25

C, 52

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

Obviamente, isso lê o código fonte e não o programa compilado - presumo que esteja dentro das especificações.

Trauma Digital
fonte
Você pode usar em printfvez de putsevitar uma nova linha à direita.
feersum
@feersum sim, boa captura
Digital Trauma
19
@DigitalTrauma É por causa de seu avatar, é claro
Peter Olson
3
Na verdade, putspode ser usado, você só precisa de readmenos caracteres.
user4098326
2
@kasperd Sim, garantido pela C89
Digital Trauma
13

PHP, 21 bytes

<?=file(__FILE__)[0];

filelê um arquivo linha por linha em uma matriz e o arquivo possui apenas uma linha. Isso economiza um byte em comparação com readfile(__FILE__).

Fabian Schmengler
fonte
Observe que isso funciona apenas a partir do PHP5.4, que foi a primeira versão a suportar a des-referenciação de array. Mas fora isso, uma ótima resposta!
Ismael Miguel
11
readfileé também 21: <?readfile(__FILE__);.
primo
11
Certo, ele não precisa<?=
Fabian Schmengler
12

Perl, 15 bytes

open 0;print<0>

Guardado 3 bytes graças a @ ThisSuitIsBlackNot !

Dom Hastings
fonte
2
Você pode salvar 3 bytes comopen 0;print<0>
ThisSuitIsBlackNot
@ThisSuitIsBlackNot eu tinha certeza de que havia uma maneira mais curta de fazê-lo, mas eu não pude durante toda a vida do meu trabalho ... Usando 0assume $0então?
Dom Hastings
3
Sim. Veja perldoc -f open: "Como atalho, uma chamada de argumento único leva o nome do arquivo da variável escalar global com o mesmo nome que o arquivo: $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";"
ThisSuitIsBlackNot 2/15/15
11

Perl 6, 20 bytes

print slurp $?FILE

Eu não trabalho com Perl 6 há muito tempo, então não tenho certeza se existem truques para tornar isso mais curto.

Teclas de atalho
fonte
2
você pode remover o segundo espaço?
Eevee
3
@Eevee, não, ele fica com raiva
Teclas de atalho
11

osascript (AppleScript na linha de comando), 40 33 32 bytes

(leia o caminho para mim) parágrafo 1

Executando em um arquivo chamado a with osascript a.

Obtém o primeiro parágrafo (linha) do arquivo e o imprime em STDOUT com uma nova linha à direita, portanto a nova linha no código.

Addison Crump
fonte
11
Veja minha edição no OP
TheInitializer
Trabalhando para fazê-lo funcionar.
Addison Crump
read path to meParece funcionar para mim. El Cap.
Digital Trauma
Não vi isso, mas foi assim que acabei fazendo. : P Obrigado, @DigitalTrauma. EDIT: as novas linhas à direita devem ser consideradas, para que você adicione a nova linha e use os parágrafos 1.
Addison Crump
11

Python 2, 32 bytes

Há uma nova linha no final do arquivo.

print open(__file__).readline()

Python 3, 33 bytes

Há uma nova linha no final do arquivo.

print(open(__file__).readline())

Graças ao feersum por capturar um problema e fornecer __file__, Loovjo por uma nova abordagem da solução Python 2 que economizou 17 bytes, e Skyler por uma solução que economizou mais um byte e funcionou tanto em Python 2 quanto em 3 (pendente printsendo uma função em Python 3)!

Doc link para readline

Celeo
fonte
Isso também economizaria 2 bytes em python3 porque você poderia descartar o endparâmetro.
quer
@ Skyler Você está absolutamente correto.
Celeo
Como isso funciona no Python 3, que precisa de parênteses print?
Maçaneta da porta
Python 3 deve ser print(open(__file__).readline())seguido por uma nova linha.
Skyler #
Seu exemplo Python 3 diz Python 2, em vez de Python 3
TheInitializer
10

Lote, 9 8 bytes

@type %0

Guardou um byte graças a @Joshua

Fabian Schmengler
fonte
3
Você pode salvar um byte, eliminando a% à direita.
Joshua
10

Python 2.7, 30 bytes

print open(__file__).read(29)

Edit: Só para esclarecer, o código acima deve ter uma nova linha no final como o 30º byte. Não estou familiarizado com a remarcação suficiente para descobrir como exibi-la no bloco de código.

Estou usando o mesmo truque aqui que o da minha submissão em C. Isso lê todo o arquivo de origem, excluindo a nova linha à direita, para dar conta da nova linha adicional que printserá anexada à saída.

xsot
fonte
Isso ocorre com o mesmo problema com a nova linha à direita que o outro envio?
Cole
Não. Deveria haver uma nova linha à direita que forma o 30º byte no código-fonte, mas não consigo exibi-lo no bloco de código. Meu envio funciona porque lê os primeiros 29 bytes do código-fonte, para que a nova linha printnão seja estranha.
Xsot #
4
Não é isso que a vírgula faz. Acrescenta um espaço em vez de uma nova linha.
xsot 30/10
2
poderia usar ␤ para indicar uma nova linha semanticamente importante
Eevee
9

Java, 212 196 bytes (171 bytes com regras de codificação questionáveis)

Obrigado ao @Cruncher por reduzi-lo em ~ 15 bytes!

Não tenho dúvida de que isso pode ser jogado.

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, outro método, usando o método estático (e o nome da classe), obtenho 171 bytes. Não tenho certeza se isso se qualifica como codificado, no entanto.

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

Usa um construtor para obter o nome da classe por um método não estático. O uso de um método estático ( A.class.getName()) era realmente codificado, então eu usei o caminho 'adequado'. Usando A.class.getName(), esse código reduz para 171 bytes.

Versões legíveis:

Usando construtor e 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 o 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"))));
    }
}

Agarra todos os bytes do arquivo de uma só vez e o envia para STDOUT. Bem direto.

Addison Crump
fonte
Por que simplesmente não usar A.class.getName()?
Fabio F.
3
É CodeGolf, não CodeReview! ;)
Fabio F.
11
@FabioF. Sim, mas acho que dança na linha de ser um nome de arquivo codificado, o que é contra as regras. O ponto é que, se você alterar o nome do arquivo, precisará alterar o nome da classe (obviamente), mas também alterar esta linha, que é como um nome de arquivo codificado.
Cruncher
11
Você não pode chamar a declaração de impressão dentro do construtor e se salvar de definir uma variável estática?
Cruncher
11
@Cruncher Nah. Você obtém o java.io, continuarei com o java.nio - o objetivo não é vencer, mas mostrar maneiras de fazê-lo de forma extremamente concisa com métodos diferentes.
Addison Crump #
8

AutoIt, 34 bytes

Emite-se na área de transferência:

ClipPut(FileRead(@ScriptFullPath))
mınxomaτ
fonte
8

Ruby, 14

$>.<<IO.read$0
histocrata
fonte
Uso legal da parte .de parênteses Evitar
Cyoce
7

Go, 111 105 bytes

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

Meu primeiro código de golfe em Go - apenas alguns truques que você pode usar aqui, eu acho.

tomasz
fonte
Já existe uma resposta no Go - isso usa o mesmo método?
Addison Crump
@VoteToClose: Eu percebo, fiquei inspirado pelo outro, mas usei a renomeação de pacotes aqui (truque barato), bem como técnicas diferentes para abrir e canalizar arquivos para o stdout. Salvei-me 22 bytes maciços ;-)
tomasz
O método é realmente um pouco diferente, bom!
Fabian Schmengler
7

PowerShell, 39 36 31 25 bytes

Tão apertado quanto eu consigo:

gc $MyInvocation.MyCommand.Path | oh

Apoiado pela demanda popular, este foi alterado para:

gc $PSCommandPath|echo -n

imprime para hospedar a saída padrão atual do shell .

Chad Baxter
fonte
gc $MyInvocation.MyCommand.Pathbasta. Ele será automaticamente impresso.
Andrew
não é garantido para especialmente se o script está sendo executado silenciosamente
Chad Baxter
Haha sim, eu não ligo. Eu ia postar se ninguém mais tivesse uma resposta do PowerShell. Mas eu esqueci que gcera um apelido e só ia usar cat, então você tinha um byte comigo lá de qualquer maneira.
Andrew
Eu não seria tão rigoroso quanto a isso. Caso contrário, cada resposta PS seria explicitamente têm de tubo para o shell host, mas isso é até você ...
Andrew
Você poderia usar gc $PSCommandPathpor 17 bytes. O problema que vejo é que isso cospe uma nova linha (que não existe na fonte). Agora é ambíguo se a nova linha à direita estiver correta ou não ... dependendo de como essas regras, talvez seja necessário fazer algo complicado gc $PSCommandPath|write-host -npor 31 bytes.
AdmBorkBork 30/10
5

C, 49 bytes

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

Editar: para esclarecer, o 49º byte é uma nova linha.

Isso lê o código fonte menos a nova linha no final, para dar conta da nova linha, que putsserá anexada ao final da saída.

xsot
fonte
Este código chama comportamento indefinido duas vezes.
Joshua
5
Bem, isso é código de golfe. Meu código produz a saída desejada, portanto é um envio válido.
Xsot #
11
@xsot Nesse caso, você provavelmente deve listar a versão do compilador + opções; caso contrário, isso pode não ser verificável.
Justin
11
Se um comportamento indefinido for permitido, desde que você possa ter algum compilador que produza a saída desejada em alguma máquina durante alguma fase da lua, então proponho int main (void) {* 0; } como uma solução. Afinal, o padrão permitiria uma implementação que compila isso em um programa que resolve o problema. Eu ficaria bem em usar o comportamento dependente da implementação, desde que você especifique o compilador, mas com um comportamento indefinido, você não pode nem garantir que não obteria dez respostas diferentes se as executasse dez vezes seguidas no mesma máquina.
Ray
11
@MDXF Eu não estava sugerindo seriamente que escrevêssemos essa solução. Eu estava argumentando contra permitir comportamentos indefinidos. int main() {*0;} pode funcionar mesmo em compiladores existentes, pois contém comportamento indefinido. Da mesma forma, a solução do xsot pode funcionar em compiladores existentes, pois contém comportamento indefinido. Nenhum deles é garantido para resolver o problema. (Embora seja mais provável que o xsot's faça isso, ele pode travar com a mesma facilidade). Meu argumento real é que devemos permitir soluções que dependam de comportamento dependente da implementação ou não especificado, mas não de comportamento indefinido.
Ray
5

Mathematica, 16 bytes

FilePrint@$Input

Execute-o no modo de script .

alefalpha
fonte
Uso o Mathematica há muitos anos e nunca ouvi falar do modo de script.
Michael Stern
4

Pitão, 25 bytes

$import sys$h'e$sys.argv

Isso lê seu nome de arquivo. Essencialmente, ele pesquisa argv, abre o arquivo correspondente ao seu último argumento e imprime sua primeira linha.

isaacg
fonte
Você não pode simplesmente fazer h'$__file__$?
kirbyfan64sos
@ kirbyfan64sos Isso me dá o erro NameError: name '__file__' is not defined. Pyth é compilado em Python e, em seguida, a sequência resultante é executada. Então, eu não esperava que isso funcionasse.
Isaacg #
4

Go, 133 bytes

Todo mundo está limpo? Ir!

package main
import("fmt"
"io/ioutil"
"runtime")
func main(){_,f,_,_:=runtime.Caller(0)
s,_:=ioutil.ReadFile(f)
fmt.Print(string(s))}
Fabian Schmengler
fonte
2
Isso me inspirou a escrever minha própria (e a primeira) solução de código-golfe no Go. Procurando alguns truques gerais, você pode facilmente diminuir para 123 caracteres aqui aplicando nomes de uma letra para pacotes, por exemplo r"runtime".
amigos estão
4

> <> , 13 bytes

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

Testado nos intérpretes online e offline. O gcomando é o mais próximo de poder ler o arquivo de origem e, se não contar para o objetivo deste desafio, marcarei minha entrada como não concorrente; Eu acredito que normalmente é considerado "trapaça" para os peixes.

Experimente online.

Cole
fonte
4

Haskell, 63 bytes

Pela ciência!

import System.Environment
main=getProgName>>=readFile>>=putStr
Craig Roy
fonte
Funciona apenas com o runhaskellcomando Muito legal
HEGX64:
4

> <> , 31 bytes

Isenção de responsabilidade: não há E / S de arquivo em> <>, no entanto, pensei que seria interessante mostrar sua E / S de espaço de código herdada do Befunge, um dos idiomas que inspirou> <>.

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

Uma Quine de leitura automática que fiz há algum tempo, você pode experimentá-la aqui .

Acabei de ver que existe um quine mais curto de leitura automática . Embora seja claramente melhor nos padrões de código-golfe, gostaria de salientar que ele possui um código codificado, enquanto o meu copia linhas ou colunas adicionais de código (desde que não quebre o código original).

Aaron
fonte
Eu estava pensando em postar em> <>, mas pensei que> <> seria impossível devido à regra: "Você deve usar a E / S do arquivo para ler o código-fonte"
Sp3000
@ Sp3000 woops, de fato, parece que eu não li o desafio o suficiente. Vou adicionar um aviso de isenção
Aaron
3

F #, 54 bytes

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

Uso:

fsi --exec a.fsx
pswg
fonte
3

Perl 5, 15 13 bytes

Agradecemos à solução Bash por inspirar isso:

print`cat $0`

Edição: Não precisa de ponto e vírgula ou primeiro espaço.

Erikster
fonte
Não é perl puro, ele precisa de algum outro executável, a saber cat, presente e localizável no $PATH. Mas se estiver presente, pode ser assumido como apenas um comando disponível para perl, então por que não.
Golar Ramblar
3

Node.js, 66 63 bytes

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

Não usa console.log, que acrescenta uma nova linha.

Félix Saparelli
fonte
11
Você pode economizar alguns bytes usando a API síncrona:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike
11
Por que não console.log(require('fs').readFileSync(process.argv[1]))\n57 bytes?
Conor O'Brien
Isso nem sempre funciona. Digamos que o arquivo seja nomeado test.js. É válido invocá-lo executando node test, o que causará um erro.
Patrick Roberts
3

C, 31 bytes

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

A solução bash é tão curta, então por que não basear uma solução C nela?

Ugoren
fonte
3

Haskell , 49 bytes

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

Experimente online!

(GHC) Haskell possui uma extensão para usar o pré-processador C (normalmente usado para portabilidade entre versões e arquiteturas). Esperamos que seja auto-explicativo.

Ørjan Johansen
fonte
3

HTML com JavaScript, 115 bytes (realmente não conta)

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

Isso conta? Eu não me importo, foi divertido :)

Tecnicamente, não abre um arquivo. Também é um documento HTML5 bem formado. O XMLSerializer foi a única ferramenta que também retornou a parte DOCTYPE, mas não é padrão. Ainda assim, ele funciona no chrome e no firefox, e aposto em outros navegadores.

E como um bônus:

JavaScript, 41 bytes

alert(document.currentScript.textContent)
Dominó
fonte
Retirar ";" no final, salve 1 byte :)
Евгений Новиков
11
@ ЕвгенийНовиков Você está certo, não sabe por que deixei isso lá na época. Parece que eu não contei isso.
Domino