Quine „zdradzająca”


56

Long-time lurker, plakat po raz pierwszy. No i proszę.

Na stronie Wikipedii dotyczącej quine napisano , że „quine jest uważane za„ oszustwo ”, jeśli patrzy na swój własny kod źródłowy”. Twoim zadaniem jest stworzenie jednego z tych „oszustów”, które będą czytały własny kod źródłowy.

To jest , więc wygrywa najkrótszy kod w bajtach - w każdym języku . Oznacza to, że 5-bajtowy skrypt Pyth nie pobiłby 21-bajtowego skryptu Python - ale 15-bajtowy skrypt Python.

Aby odczytać kod źródłowy, musisz użyć pliku I / O, więc następujący kod JavaScript, pobrany z oficjalnej strony Wikipedii, jest nieprawidłowy:

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

Musi uzyskać dostęp do kodu źródłowego pliku na dysku .

Nie możesz podać nazwy pliku. Musisz wykryć samą nazwę pliku.

Czy wszystko jasne? Iść!


1
Czy końcowe znaki nowego wiersza nie są obecne w oryginalnym pliku?
isaacg

3
@isaacg IMHO To nie jest quine, ponieważ nie jest to kod źródłowy.
mınxomaτ

3
Należy podać wymóg, aby określał on rzeczywistą nazwę pliku zamiast zakładać na stałe ciąg znaków dla lokalizacji źródłowej.
feersum

3
Zgadzam się z @feersum, że wymaganie określonej nazwy pliku sprawia, że ​​wyzwanie staje się banalne.
mınxomaτ

1
Czy możemy założyć, że (dla skompilowanych języków) kod źródłowy znajduje się w tym samym folderze (tzn. Możemy po prostu dodać „.cpp” lub „.hs” do arg [0], aby uzyskać źródło).
HEGX64

Odpowiedzi:


60

Zsh , 4 bajty

<$0

Powłoka Z ma wbudowane funkcje kotów. Czwarty znak to linia.

Wypróbuj online!

Kod nie zależy w żaden sposób od nazwy pliku; działa, nawet jeśli nazwa pliku zawiera znaki specjalne, takie jak spacje lub znaki nowej linii.

Testowe uruchomienie

$ 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 bajtów

cat $0

Gruntownie.


3
Nie drukuje nowego wiersza.
Addison Crump

2
catnie dołącza nowego wiersza (przynajmniej w moim systemie).
spaghetto

7
@isaacg catdrukuje zawartość dostarczonego pliku bajt na bajt.
Dennis

2
@LukStorms Ale czy nie byłoby to catrozwiązanie zamiast bashrozwiązania? I cat tak naprawdę nie kwalifikuje się jako język programowania
Fabian Schmengler

30
Czy to zadziała, jeśli plik ma nazwę -e?
Mark Plotnick

32

Program ładujący wykonywalny UNIX, 10 bajtów

#!/bin/cat

Jeśli nie obchodzi Cię spam związany ze standardowym błędem, możesz go skrócić o jeden bajt:

#!/bin/dd

7
Lubię to. Nie jestem jednak pewien, czy kwalifikuje się jako „język”.
Kevin

Być może trochę oszukujesz, ale czy nie możesz zmienić nazwy folderu bin i programu cat, aby skrócić ścieżkę?
James Webster

3
Nie sugeruję, że robisz btw. Sugeruję, byś mógł
James Webster

3
@Kevin „Językiem” (czyli tłumaczem) jest cat. Sądzę, że jeśli chcesz być bardzo konkretny, catprogram po prostu drukuje się i jest kompatybilny z każdym istniejącym formatem pliku :)
l0b0

1
@JamesWebster sudo install /bin/cat /c. Wiesz, na wszelki wypadek /binnie w głównym systemie plików. Muszę to mieć catw singleuser…
Blacklight Shining

25

C, 52

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

Oczywiście, to czyta kod źródłowy, a nie skompilowany program - zakładam, że jest to zgodne ze specyfikacją.


Możesz użyć printfzamiast, putsaby uniknąć końcowego nowego wiersza.
feersum

@feersum tak, dobry haczyk
Digital Trauma

19
@DigitalTrauma To oczywiście z powodu twojego awatara
Peter Olson

3
Właściwie putsmożna go użyć, wystarczy mieć readmniej znaków.
user4098326,


13

PHP, 21 bajtów

<?=file(__FILE__)[0];

fileczyta plik linia po linii do tablicy, a plik ma tylko jedną linię. To oszczędza bajt w porównaniu do readfile(__FILE__).


Zauważ, że działa to tylko od PHP5.4 i wyższych, które były pierwszą wersją obsługującą odreferencje tablic. Ale poza tym całkiem ładna odpowiedź!
Ismael Miguel

1
readfileJest też 21: <?readfile(__FILE__);.
primo

1
Racja, nie potrzebuje<?=
Fabian Schmengler

12

Perl, 15 bajtów

open 0;print<0>

Zaoszczędzono 3 bajty dzięki @ ThisSuitIsBlackNot !


2
Możesz zapisać 3 bajty za pomocąopen 0;print<0>
ThisSuitIsBlackNot

@ThisSuitIsBlackNie byłem pewien, że istnieje krótszy sposób, aby to zrobić, ale nie mogłem przez całe życie pracować nad tym ... Używanie 0zakłada $0?
Dom Hastings,

3
Tak. Zobacz perldoc -f open: „Jako skrót jednoargumentowe wywołanie pobiera nazwę pliku z globalnej zmiennej skalarnej o tej samej nazwie co uchwyt pliku: $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";
ThisSuitIsBlackNot

11

Perl 6, 20 bajtów

print slurp $?FILE

Nie pracowałem bardzo długo z Perlem 6, więc nie jestem pewien, czy są jakieś sztuczki, które mogłyby go skrócić.


2
czy możesz usunąć drugie miejsce?
Eevee,

3
@Eevee nie, robi się zły
Hotkeys

11

osascript (AppleScript z wiersza poleceń), 40 33 32 bajty

(przeczytaj ścieżkę do mnie) akapit 1

Wykonanie na pliku o nazwie z osascript a.

Pobiera pierwszy akapit (linię) pliku i drukuje go do STDOUT ze znakiem nowej linii, a zatem nowej linii w kodzie.


1
Zobacz moją edycję do OP
TheInitializer

Pracuję nad tym, aby to zadziałało.
Addison Crump

read path to mewydaje się działać dla mnie. El Cap.
Digital Trauma

Nie widziałem tego, ale tak właśnie skończyłem. : P Dzięki, @DigitalTrauma. EDYCJA: należy wziąć pod uwagę końcowe znaki nowej linii, więc dodajesz nową linię i używasz ust. 1.
Addison Crump

11

Python 2, 32 bajty

Na końcu pliku znajduje się nowa linia.

print open(__file__).readline()

Python 3, 33 bajty

Na końcu pliku znajduje się nowa linia.

print(open(__file__).readline())

Dzięki feersum za złapanie problemu i dostarczenie __file__, Loovjo za nowe podejście do rozwiązania Python 2, które pozwoliło zaoszczędzić 17 bajtów, a Skyler za rozwiązanie, które pozwoliło zaoszczędzić kolejny bajt i działało zarówno w Pythonie 2, jak i 3 (w oczekiwaniu printna funkcję w Pythonie 3)!

Link do dokumentu dla readline


Pozwoliłoby to również zaoszczędzić 2 bajty w python3, ponieważ można odrzucić endparametr.
Skyler

@Skyler Masz absolutną rację.
Celeo,

Jak to działa w Pythonie 3, który wymaga parens print?
Klamka

Po Pythonie 3 powinna print(open(__file__).readline())następować nowa linia.
Skyler

Twój przykład w Python 3 mówi Python 2 zamiast Python 3
TheInitializer


10

Python 2.7, 30 bajtów

print open(__file__).read(29)

Edycja: Żeby było jasne, powyższy kod powinien mieć nowy wiersz na końcu jako 30 bajt. Nie znam wystarczająco znaczników, aby dowiedzieć się, jak wyświetlić go w bloku kodu.

Używam tutaj tej samej sztuczki, co w moim przesłaniu C. Odczytuje to cały plik źródłowy z wyłączeniem końcowego nowego wiersza, aby uwzględnić dodatkowy nowy wiersz, który printzostanie dołączony do wyniku.


Czy ma to ten sam problem z końcowym znakiem nowej linii, co inne przesłanie?
cole

Nie. Powinien być końcowy znak nowej linii, który tworzy 30 bajt w kodzie źródłowym, ale nie mogę go wyświetlić w bloku kodu. Moje przesłanie działa, ponieważ odczytuje pierwsze 29 bajtów kodu źródłowego, aby nowa linia od printnie była obca.
xsot

4
Nie to robi przecinek. Dodaje spację zamiast nowej linii.
xsot

2
mógłby użyć ␤ do wskazania semantycznie ważnego nowego wiersza
Eevee,

9

Java, 212 196 bajtów (171 bajtów z wątpliwymi regułami kodowania twardego)

Dzięki @Cruncher za skrócenie go o ~ 15 bajtów!

Nie mam wątpliwości, że można grać w golfa.

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

Lub inną metodą, używając metody statycznej (i nazwy klasy), otrzymuję 171 bajtów. Nie jestem jednak pewien, czy to kwalifikuje się jako zakodowane na stałe.

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

Używa konstruktora, aby uzyskać nazwę klasy metodą niestatyczną. Zastosowanie metody statycznej ( A.class.getName()) było naprawdę mocno zakodowane, więc użyłem „właściwej” metody. Za pomocą A.class.getName()tego kodu skraca się do 171 bajtów.

Wersje czytelne:

Korzystanie z konstruktora i 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) {}
    }
}

Za pomocą metody statycznej 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"))));
    }
}

Pobiera wszystkie bajty pliku na raz i wysyła je do STDOUT. Całkiem proste.


Dlaczego po prostu nie użyć A.class.getName()?
Fabio F.

3
To CodeGolf, a nie CodeReview! ;)
Fabio F.

1
@FabioF. Tak, ale myślę, że tańczy na linii bycia zakodowaną nazwą pliku, co jest niezgodne z regułami. Chodzi o to, że jeśli zmienisz nazwę pliku, musisz zmienić nazwę klasy (oczywiście), ale także zmienić tę linię, która jest jak zakodowana nazwa pliku.
Cruncher

1
Czy nie możesz wywołać instrukcji print wewnątrz konstruktora i uchronić się przed ustawieniem zmiennej statycznej?
Cruncher

1
@Cruncher Nah. Dostajesz java.io, ja pozostanę przy java.nio - nie chodzi o to, aby wygrać, ale pokaż sposoby, jak to zrobić niezwykle zwięźle różnymi metodami.
Addison Crump

8

AutoIt, 34 bajty

Wysyła się do schowka:

ClipPut(FileRead(@ScriptFullPath))


7

Idź, 111 105 bajtów

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

Mój pierwszy golf w Go w Go - chyba kilka sztuczek, których możesz tu użyć.


W Go jest już odpowiedź - czy używa tej samej metody?
Addison Crump

@VoteToClose: Zdaję sobie sprawę, zainspirowałem się tym drugim, ale użyłem tutaj zmiany nazwy pakietu (tania sztuczka), a także innej techniki otwierania i przesyłania potokiem pliku na standardowe wyjście. Zaoszczędził mi masę 22 bajtów ;-)
tomasz

Metoda jest nieco inna, dobra!
Fabian Schmengler

7

PowerShell, 39 36 31 25 bajtów

O tak ciasno, jak tylko mogę:

gc $MyInvocation.MyCommand.Path | oh

W związku z popularnym żądaniem zmieniono to na:

gc $PSCommandPath|echo -n

wypisuje na bieżące standardowe wyjście powłoki powłoki .


gc $MyInvocation.MyCommand.Pathwystarczy. Automatycznie go wydrukuje.
Andrew

nie ma gwarancji, że szczególnie, jeśli skrypt działa cicho
Chad Baxter,

Haha tak, nie obchodzi mnie to. Zamierzałem pisać, jeśli nikt inny nie miał odpowiedzi PowerShell. Ale zapomniałem, że to gcbył pseudonim i właśnie zamierzałem go użyć cat, więc i tak miałeś na mnie bajt.
Andrew

Nie byłbym wobec tego tak surowy. W przeciwnym razie każda odpowiedź PS musiałaby jawnie przesyłać do powłoki hosta, ale to zależy od ciebie ...
Andrew

Zamiast tego możesz użyć gc $PSCommandPath17 bajtów. Problem, jaki widzę, polega na tym, że wyrzuca to nowy wiersz (który nie istnieje w źródle). Teraz jest dwuznaczne, czy końcowe znaki nowej linii są w porządku, czy nie ... w zależności od tego, jak to rządzi, być może będziemy musieli zrobić coś trudnego, jak gc $PSCommandPath|write-host -nna 31 bajtów.
AdmBorkBork


5

C, 49 bajtów

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

Edycja: Aby wyjaśnić, 49 bajt jest znakiem nowej linii.

Odczytuje kod źródłowy minus nowy wiersz na końcu, aby uwzględnić nowy wiersz, który putszostanie dołączony na końcu wyniku.


Ten kod dwukrotnie wywołuje niezdefiniowane zachowanie.
Joshua

5
To jest golf golfowy. Mój kod generuje pożądane dane wyjściowe, więc jest to prawidłowe przesłanie.
xsot

1
@xsot W takim przypadku powinieneś prawdopodobnie podać wersję kompilatora + opcje; w przeciwnym razie może nie być to weryfikowalne.
Justin

1
Jeśli posiadanie niezdefiniowanego zachowania jest dozwolone, o ile możesz mieć jakiś kompilator, który wytwarza pożądaną moc wyjściową na jakiejś maszynie podczas pewnej fazy księżyca, to proponuję int main (void) {* 0; } jako rozwiązanie. W końcu standard zezwala na implementację, która kompiluje to w program, który rozwiązuje problem. Mogłabym używać zachowania zależnego od implementacji, o ile określisz kompilator, ale przy nieokreślonym zachowaniu nie możesz nawet zagwarantować, że nie otrzymasz dziesięciu różnych odpowiedzi, jeśli uruchomisz to dziesięć razy z rzędu w ta sama maszyna.
Ray

1
@MDXF Nie sugerowałem poważnie, żebyśmy napisali to rozwiązanie. Argumentowałem przeciwko dopuszczeniu nieokreślonego zachowania. int main() {*0;} może działać nawet na istniejących kompilatorach, ponieważ zawiera niezdefiniowane zachowanie. Podobnie, rozwiązanie xsot może działać na istniejących kompilatorach, ponieważ zawiera niezdefiniowane zachowanie. Żadne z nich nie gwarantuje rozwiązania problemu. (Chociaż jest prawdopodobne, że xsot's to zrobi, równie łatwo może ulec awarii). Moim faktycznym argumentem jest to, że powinniśmy dopuścić rozwiązania zależne od zachowania zależnego od implementacji lub nieokreślonego, ale nie zachowania niezdefiniowanego.
Ray


4

Pyth, 25 bajtów

$import sys$h'e$sys.argv

To czyta jego nazwę pliku. Zasadniczo wyszukuje argv, otwiera plik odpowiadający jego ostatniemu argumentowi i wypisuje swój pierwszy wiersz.


Nie możesz po prostu zrobić h'$__file__$?
kirbyfan64sos

@ kirbyfan64sos To daje mi błąd NameError: name '__file__' is not defined. Pyth jest kompilowany do Pythona, a następnie powstaje ciąg wynikowy. Więc nie spodziewałbym się, że to zadziała.
isaacg

4

Idź, 133 bajtów

Czy wszystko jasne? Iść!

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

2
Zainspirowało mnie to do napisania własnego (i pierwszego) rozwiązania do gry w golfa w Go. Szukając ogólnych sztuczek, możesz łatwo zejść do 123 znaków, stosując na przykład nazwy jednoliterowe dla paczek r"runtime".
tomasz

4

> <> , 13 bajtów

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

Testowany zarówno na tłumaczach online, jak i offline. gKomenda znajduje się najbliżej jest w stanie odczytać z pliku źródłowego, a jeśli to się nie liczy dla celów tego wyzwania będę oznaczyć wpis zakaz konkurowania; Uważam, że normalnie uważa się to za „oszukiwanie” dla quines.

Wypróbuj online.


4

Haskell, 63 bajty

Dla nauki!

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

Działa tylko z runhaskellpoleceniem. Bardzo fajnie
HEGX64

4

> <> , 31 bajtów

Oświadczenie: nie ma we / wy pliku w> <>, ale pomyślałem, że byłoby interesujące zaprezentowanie we / wy przestrzeni kodowej odziedziczonej po Befunge, jednym z języków, który zainspirował> <>.

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

Samouczące się Quine, które stworzyłem jakiś czas temu, możesz spróbować tutaj .

Właśnie widziałem, że jest krótszy samouczący się quine . Chociaż jest wyraźnie lepszy w standardach golfa kodowego, chciałbym zauważyć, że ma on zakodowaną długość kodu, podczas gdy moje kopiowałyby dodatkowe wiersze lub kolumny kodu (o ile nie łamią oryginalnego kodu).


Myślałem o opublikowaniu w> <>, ale pomyślałem, że> <> byłoby niemożliwe ze względu na zasadę: „Musisz użyć I / O pliku, aby odczytać kod źródłowy”
Sp3000,

@ Sp3000 woops, wygląda na to, że nie przeczytałem wystarczająco dobrze wyzwania. Dodam zastrzeżenie
Aaron

3

F #, 54 bajtów

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

Stosowanie:

fsi --exec a.fsx

3

Perl 5, 15 13 bajtów

Podziękowania dla rozwiązania Bash za inspirację:

print`cat $0`

EDYCJA: Nie potrzebujesz średnika ani pierwszej spacji.


Nie jest to czysty perl, potrzebuje innego pliku wykonywalnego, a mianowicie catobecnego i możliwego do znalezienia w $PATH. Ale jeśli jest obecny, można przyjąć, że jest to po prostu polecenie dostępne perl, więc dlaczego nie.
Golar Ramblar

3

Node.js, 66 63 bajtów

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

Nie używa console.log, który dodaje nowy wiersz.


1
Możesz zapisać kilka bajtów, używając synchronicznego interfejsu API:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike

1
Dlaczego nie console.log(require('fs').readFileSync(process.argv[1]))\nza 57 bajtów?
Conor O'Brien

To nie zawsze działa. Powiedz, że plik ma nazwę test.js. Prawidłowe jest wywołanie go przez uruchomienie node test, co spowoduje zgłoszenie błędu.
Patrick Roberts,


3

Haskell , 49 bajtów

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

Wypróbuj online!

(GHC) Haskell ma rozszerzenie do korzystania z preprocesora C (powszechnie używanego do przenoszenia między wersjami i architekturami.) Mam nadzieję, że to oczywiste.


3

HTML z JavaScript, 115 bajtów (tak naprawdę się nie liczy)

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

Czy to się liczy? Nie mam nic przeciwko, było fajnie :)

Technicznie nie otwiera pliku. Jest to również dobrze sformułowany dokument HTML5. XMLSerializer był jedynym narzędziem, które również zwróciło część DOCTYPE, ale jest niestandardowe. Mimo to działa na Chrome i Firefox, i założę się o inne przeglądarki.

I jako bonus:

JavaScript, 41 bajtów

alert(document.currentScript.textContent)

Usuń „;” na koniec, zachowaj 1 bajt :)
Евгений Новиков

1
@ ЕвгенийНовиков Masz rację, nie jestem pewien, dlaczego wtedy to zostawiłem. Wygląda na to, że tego nie policzyłem.
Domino
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.