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!


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

28
feline functionalities:)
theB

48

Bash, 6 bytes

cat $0

Basicamente.


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

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.


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


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__).


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 !


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.


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.


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


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

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.


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.


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


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.


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 .


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.


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


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.


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

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.


4

Haskell, 63 bytes

Pela ciência!

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

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).


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

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.


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.


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?


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.


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)

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.