Jestem programistą i nie mam ochoty wykonywać swojej pracy. Wiem z XKCD, że najlepszą wymówką do zwolnienia się jest kompilacja twojego kodu . Z tego powodu myślę, że potrzebuję kodu, który skompiluje się na zawsze! A ponieważ jestem leniwy i nie chcę dużo pisać, należy to zrobić przy użyciu możliwie najkrótszego kodu.
Twoim zadaniem jest napisanie programu, który jest poprawny pod względem składniowym, ale spowoduje, że kompilator przejdzie w nieskończoną pętlę.
Dane techniczne
- Oczywiście musisz użyć języka, który ma kompilator.
- Określ implementację używaną w każdym rozwiązaniu.
- To jest golf golfowy , więc wygrywa najkrótsze prawidłowe rozwiązanie (w bajtach).
- Kompilator może zakończyć brak pamięci lub stosu.
code-golf
compile-time
Esolanging Fruit
źródło
źródło
Java
: zdefiniuj procesor adnotacji (fragment ideone), którego będziesz używać podczas wywoływaniajavac
z jego-processor
opcja. Dzięki temu kompilacja dowolnej klasy zawiesza się na zawsze.Odpowiedzi:
Japt , 2 bajty
Możesz to przetestować online tutaj , ale nie poleciłbym tego, ponieważ spowoduje to zawieszenie przeglądarki.
Wyjaśnienie
Japt używa biblioteki shoco do kompresji ciągów. Strzałka wsteczna mówi kompilatorowi, aby wszystko zdekompresował do następnego kliknięcia wstecznego lub do końca pliku. Każdy bajt wykonuje następujące czynności:
00-7F
pozostają nienaruszone.80-BF
każdy przekształcić wspólnej małymi pary dwuliterowy (at
,oo
,th
, itd.).C0-DF
każdy zużywa następny bajt i przekształca we wspólny czteroliterowy ciąg .E0-EF
każdy zużywa kolejne trzy bajty i przekształca we „wspólny” ciąg ośmioliterowy (zaczynając odWhererer
i schodząc stamtąd).F0-F7
zepsuć dekompresor, choć nadal wszystko zwraca do bajtu łamania.F8-FF
powoduje wejście dekompresora w nieskończoną pętlę. Nie jestem pewien, dlaczego tak jest, ponieważ nie jestem bardzo zaznajomiony z wewnętrznymi funkcjami biblioteki shoco (a kod JavaScript jest całkowicie nieczytelny ), ale w tym przypadku jest całkiem przydatny.Nie wierzę, że istnieje inny sposób na bałagan z kompilatorem Japt, ale nigdy nie wiesz ...
źródło
TikZ (pdfTeX 3.14159265-2.6-1.40.17),
857974242221 bajtówPęczek bajtów zaoszczędzonych dzięki wchargin
Jeden bajt zaoszczędzony dzięki Chrisowi H.
Zetknąłem się z nią przypadkiem, kiedy pracowałem nad pracą domową. Sporo czasu czekałem, aż się skompiluje, zanim zdałem sobie sprawę, co się dzieje.
Składa się z dwóch części:
Spowoduje to załadowanie pakietu TikZ
i:
To uruchamia
\tikz
środowisko i polecenie rysowania.Co się dzieje
Kompilator pdflatex ma problemy
\tikz\pic
i wchodzi w tryb interaktywny, powodując jego zatrzymanie na czas nieokreślony.źródło
\draw l\end {document}
Plik zakończony podczas skanowania\tikz@next.
” pdflatex 3.1415926-2.5-1.40.14 (TeX Live 2013 / Debian). tikz 2010/10/13 v2.10. Jest to standardapt install texlive-full
w Ubuntu 14.04.pdfTeX 3.14159265-2.6-1.40.17 (TeX Live 2016)
i rzeczywiście zapętla się w nieskończoność. Dzięki za wskazówki.\pic
zamiast \ draw` - dokładnie takie samo zachowanie (testowane przy użyciu tikz 1.142)\def\a{\a}\a
(12 bajtów)? Lub, ponieważ jest to kod golfowy i~
domyślnie jest aktywny\def~{~}~
(9 bajtów)?C, 18 bajtów
Kompilatory zwykle poddają się po rekurencji około 200 razy.
Czy konstrukcja DOM liczy się jako etap kompilacji? Jeśli tak, to
x.htm
:źródło
<?include __FILE__;
.Java,
10295898878 bajtówKończy się to,
StackOverflowError
co się dzieje, ponieważ ogólny system rozstrzygania nie może zdecydować o katalogu głównym, na podstawie którego należy rozstrzygnąć inne ogólne.Kredyty należne .
co się tutaj stało?
A<T>
jest tam, aby mieć 1-literowego rodzica. To jest ogólne. Mógłbym użyćList
, ale import i powtarzanie 4 liter są zbyt długie.B<T>
deklaruje podstawowy rodzajowy.B extends A
wymagana jest hierarchia międzyB
iA
.extends A<A>
tworzy własne odniesienie naA<T>
.A<? super B>
włącza wyszukiwanie generyczneA<T>
B<B<T>>
tworzy odniesienie naB<T>
.A<...> a=new B<>()
wymusza użycie ogólnych, zamiast po prostu ich definicji, wymuszając rozdzielczość podczas kompilacjiB
, a nie później.A<?super B
tworzy brak odniesienia do siebie, więc mamy zarówno odniesienie do jednego typu, jak i do drugiego w ogólnych nazwachA
.B<A>
tworzy brak odniesienia do siebie, więc mamy zarówno odniesienie do jednego typu, jak i do drugiego w ogólnych nazwachB
.Teraz typ
A
ma rodzaj ogólnyA
iB
, ale który należy wybrać? Zapomnij o sobie, spróbujmy rozwiązaćB
. Świst.Okej, czy
B
ma rodzaj generycznyA
iB
, ale który wybrać? Zapomnij o sobie, spróbujmy rozwiązaćA
. PongTen rodzaj rekursji naprawdę nie można być unikane, ponieważ istnieją uzasadnione przypadki, takie jak
A<B<A<B<A<B<Object>>>>>>
na przykład: obiekt JSON:List<Map<String,Map<String,List<Map<String,List<String>>>>>>
.Wynik kompilacji
W moim systemie ślad stosu zatrzymuje się po wyświetleniu 1024 linii, które w rzeczywistości są 4 tymi samymi liniami powtórzonymi 256 razy, co dowodzi nieskończonej rekurencji. Oszczędzę ci cały ten ślad.
Oszczędności
interface
+implements
znakiemclass
+extends
.Long
sięA
(dwa razy).new B<A>()
→new B<>()
).źródło
class A<T>{}class B<T>extends A<A<?super B<B<T>>>>{A<?super B<A>>b=new B<>();}
B
zawiera niezdecydowane odwołanie do ogólnego,A
które z kolei zawiera nierozstrzygalne odwołanie do ogólnej. B. Kiedy resolver nie może zdecydować, sprawdza dołączone odwołania, ale tutaj obie ogólne odnoszą się do siebie w nierozstrzygalny sposób (głównie dzięki samodzielnym odnośnikom isuper
słowu kluczowemu. Więc resolver faktycznie ping-pong między dwoma rodzajami.public @interface X {@X(x=X.class)Class<? extends X> x();}
... Ale szybko zdałem sobie sprawę, dlaczego to nie zadziała lol.GNU Makefile,
87 bajtówJeden bajt zaoszczędzony dzięki KonradRudolph
Zapisane jako
Makefile
i przywołane przezmake
:Spowoduje to nieskończoną rekurencję kompilacji pierwszego znalezionego celu
"x"
.Nie trzeba dodawać, że tak naprawdę nie chcesz uruchamiać tej bomby widelcowej na serwerze produkcyjnym. :-)
Alternatywna wersja, 5 bajtów
Sugerowane przez KonradRudolph:
$_
jest odniesieniem do ostatniego argumentu poprzedniego polecenia. Mówiąc dokładniej, rozwiązuje się tutaj jako bezwzględną ścieżkę do wykonywanego polecenia - które jestmake
samo w sobie.Powinno to działać dobrze w oryginalnym środowisku Bash, ale nie na Windows + MinGW.
źródło
make
tak naprawdę kompiluje Makefile (tylko go interpretuje).C ++,
6058To rekurencyjnie tworzy wystąpienia
class a
z różnymi parametrami szablonu. GCC 7.0 zatrzymuje się po 900 poziomach rekurencji z mnóstwem błędów związanych zoperator->
byciem prywatnym, ale na przykład ICC 17 i Microsoft (R) C / C ++ Optimization Compiler 19 limit czasu na godbolt .Problem w tym, że prawdopodobnie w niektórych kompilatorach zabraknie pamięci w pewnym momencie, więc nawet bez limitów rekurencyjnych to się skończy. To samo prawdopodobnie dotyczy również odpowiedzi Clojure.
Edycja: 2 bajty zapisane przez bolov - Dzięki
źródło
a<int>i=i->b;
operator->
są domyślnie prywatne w klasie. Wewnątrz struktury jest publiczny i dlategoi->b
może uzyskać do niego dostęp.Perl ,
1513 bajtówWypróbuj online!
Teraz z zapisanymi 2 bajtami: @Zaid przypomniał mi o szybszym sposobie wykonania pętli w Perlu.
Jest to dość proste: po prostu instaluje hak analizatora składni z nieskończoną pętlą, co powoduje, że analizowanie kodu zajmuje nieskończenie dużo czasu. (Perl jest fajny, ponieważ pozwala na uruchamianie dowolnego kodu w środku analizy; haczyki analizatora są określone w samym Perlu i często używane do robienia rzeczy takich jak import bibliotek lub zmiana reguł parsowania dla identyfikatora, który chcesz traktować jak słowo kluczowe.) Wypróbuj online! powyższy link daje
-c
opcję (aby skompilować kod w celu zweryfikowania poprawności składni, ale nie uruchomić jej), aby udowodnić, że nieskończona pętla dzieje się w czasie kompilacji.Jeśli zastanawiasz się nad „czasem kompilacji” w języku skryptowym: Perl faktycznie kompiluje się do kodu bajtowego, a następnie uruchamia kod bajtowy, ale jest to szczegół, który rzadko ma znaczenie przy programowaniu. Rodzina
-MO=
opcji wiersza poleceń może być używana do robienia rzeczy z kodem bajtu innym niż jego uruchomienie (chociaż nie z tym programem, ponieważ nieskończona pętla ma miejsce przed wygenerowaniem kodu bajtu).źródło
a:goto a
też wygląda ładnie (ten sam bytecount niestety).BEGIN{{redo}}
zaoszczędzi ci kilka bajtówC ++,
373029 bajtówWykorzystuje przyszły parametr funkcji automatycznej. Został on zaproponowany do C ++ 17, ale nie sądzę, że się udało.
gcc
obsługuje jednak to jako rozszerzenie.Gruntownie
jest równa
Kod próbuje utworzyć instancję
f
rekurencyjnie z różnymi argumentami szablonu.gcc
nie działa zDzięki
-ftemplate-depth=10000
niemu mogę wypluć „Zabity - czas przetwarzania przekroczony” na Godbolt.Sprawdź to na Godbolt
1 bajt zapisany przez Quentin. Dziękuję Ci.
źródło
int
jako typu zwrotu :)auto
parametry funkcji nie dostały się do C ++ 17; a takżeint f() { ... }, a;
nie jest prawnym oświadczeniem podczas ostatniej kontroli. (Nie można mieszać deklaracji funkcji z takimi deklaracjami zmiennych). To, co tu masz, to bardzo specyficzny dla GCC dialekt języka C ++. Nie to, że w tym kontekście jest z tym coś nie tak. :)Common Lisp, 8 bajtów
Kompilator spróbuje odczytać formularz i napotka makro makra sharpsign-dot , które ocenia kod w czasie odczytu i wykorzystuje jego wynik jako formę do kompilacji. Tutaj wykonywany kod jest nieskończoną pętlą.
źródło
TeX, 9 bajtów
TeX działa poprzez rozwijanie makr. Przez większość czasu makra TeXa (zwane również sekwencjami kontrolnymi ) mają taką formę,
\name
ale możliwe jest również zdefiniowanie niektórych znaków jako makr, które są nazywane aktywnymi znakami . Znak~
jest domyślnie aktywny w zwykłym TeX-ie, dlatego można go używać jako nazwy makra bez dalszych deklaracji. W\def~{~}
powyższym definiuje się~
tak, że rozwija się do~
. Oznacza to, że za każdym razem, gdy TeX napotka~
, zastępuje je,~
a następnie ponownie bada zastąpienie, co oznacza, że napotyka całkowicie nowe wystąpienie~
i zastępuje je~
. To definiuje nieskończoną pętlę. Wszystko, co jest wtedy potrzebne, to uruchomienie pętli i to właśnie~
robi finał .Dodano w edycji
Aby to poprawnie skompilować , wywołaj jako:
-ini
Flaga mówi, żepdftex
należy opracować nowy format. Jest to wstępnie skompilowany zestaw definicji, które można załadować, gdy TeX zostanie później wywołany w celu przyspieszenia przetwarzania dokumentu (LaTeX2e jest tego przykładem). Myślę, że&pdftex
dodaje kilka bajtów, co daje w sumie 17.źródło
pdftex
programie jako o „interpretacji” danych wejściowych TeX w celu wygenerowania pliku PDF jako „danych wyjściowych” - w ten sam sposób, w jakig++
program „interpretuje” dane wejściowe C ++ w celu utworzenia pliku .exe jako „danych wyjściowych”. ;)Haskell, 25 + 17 = 42 bajty
Prosty metaprogram Haskella, który definiuje nieskończoną wartość i próbuje obliczyć tę wartość w czasie kompilacji.
Wywołaj za pomocą
ghc -XTemplateHaskell <file.hs>
(+17 dla parametru do kompilatora)źródło
$(let a=a in a)
działa (dla 32 bajtów)?let a = a in a
zostaje przepisana na wyjątek, który po prostu powoduje błąd kompilatora w przeciwieństwie do nieskończonej pętli. (chociaż może to działałoby z innym kompilatorem Haskell, ale nie mam go pod ręką, aby spróbować)Exception when trying to run compile-time code: <<loop>>
zarówno w interpreterie, jak i podczas kompilacji ... technicznie powyższy kod umiera również z wyjątkiem, ale przepełnienie stosu, które jest wyraźnie dozwolone przez specyfikację - a gdybyś miał nieskończoną pamięć, zapętliłaby się na zawsze. Te<<loop>>
pożary wyjątków daleko przed moja maszyna zabraknie pamięci.klasa,
109 bajtówz powyższym kodem umieszczonym w
build.gradle
pliku. Gradle używa groovy jako języka podstawowego, więc naprawdę mówimy tutaj o groovy, ale ponieważ pytanie dotyczyło czasu kompilacji, pomyślałem, że gradle będzie bardziej odpowiedni.Uruchomienie dowolnych poleceń kompilacji stopni z powyższym kodem powoduje wydrukowanie linii statusu kompilacji kompatybilnej z szefem włosów:
jeśli chcesz podbić, dodaj
-d
flagę debugowania dla:który oprócz imponująco skomplikowanego wyglądu aktualizuje również nowy zestaw:
linie stanu co 10 sekund, dzięki czemu wygląda na to, że kompilacja jest zajęta robieniem ważnych technicznych ... rzeczy.
źródło
SWI-Prolog, 34 bajty
Wyjaśnienie
term_expansion/2
to coś, co jest automatycznie wywoływane przez kompilator przed faktyczną kompilacją kodu w celu przekształcenia niektórych terminów w kodzie źródłowym w inne.Poniżej przedstawiamy nową regułę
term_expansion/2
:repeat,1=0.
.repeat/0
jest predykatem, który zawsze się udaje i zapewnia nieskończoną liczbę punktów wyboru.1=0
stara się zjednoczyć1
z0
, co zawszefalse
. Spowoduje to powrót kompilatora dorepeat
(ponieważ zawsze zapewnia punkt wyboru) i ponowienie próby1=0
itp.źródło
expand_term
zamiast tego (jak mówi,term_expansion
nie można używać tak jak tutaj w GNU Prolog).expand_term
Jednak nie działa z SWI.Marka GNU, 44
Nie mogę ubiegać się o kredyt. Wywodzi się z książki Roberta Mecklenburga Managing Projects with GNU Make: The Power of GNU Make for Building Anything .
Wolę to od drugiej Utwórz odpowiedź, ponieważ nie używa rekurencji. Na mojej maszynie wirtualnej druga odpowiedź Make kontynuuje rozwidlanie procesów i gdzieś na głębokości około 7 000 maszyn wirtualnych nie reaguje. Jednak dzięki tej odpowiedzi można kontynuować w nieskończoność bez zużywania zasobów systemowych. Dzięki tej kompilacji naprawdę będziesz mógł się zwolnić. Przeszedłem ponad 1 000 000 iteracji bez widocznej degradacji systemu.
Uwaga: Musiałem dodać
sleep 1
tak, aby znacznik czasu makefile był aktualizowany za każdym razem. Możesz to zmienić,sleep 0.01
jeśli chcesz, aby przechodził przez iteracje nieco szybciej.źródło
GNU Forth, 15 bajtów
Grał w golfa
Ponownie definiuje (ponownie kompiluje) słowo
:
i wywołuje natychmiastową nieskończoną pętlę[do] [loop]
wewnątrz nowej definicji (dokładnie w czasie kompilacji).Wypróbuj online!
źródło
Clojure, 21 bajtów
Związuje kompilator, definiując makro, które wielokrotnie emituje wywołania do siebie.
W moim telefonie powoduje to zawieszenie się REPL i opóźnienie urządzenia. Na moim laptopie nie udaje się to z StackOverflow.
Niestety StackOverflow dzieje się natychmiast, ale nadal obowiązuje zgodnie z regułami.
źródło
MSBuild, 130 bajtów
Zapisz to jako plik z
.proj
rozszerzeniem i uruchom zmsbuild
wiersza polecenia. MSBuild uruchomi swój jedyny cel, który po prostu spawnuje innymsbuild
proces.źródło
C, 31 bajtów
Inspirowany Digital Trauma . Skompiluj z
-mcmodel=medium
flagą.Powodzenia w kompilowaniu tego, potrzebujesz 1,8 yottabajtów pamięci RAM i miejsca na dysku.
źródło
Mathematica 33 bajtów
Kod podejmie próbę symbolicznej oceny argumentu przed kompilacją, a sam argument jest nieskończoną pętlą. Funkcja While ma drugi zerowy argument, ponieważ nie jest ważny.
źródło
Compile
połączenia, czy przed nim?Haskell (GHC, bez szablonu Haskell lub niestandardowych reguł przepisywania) , 138
Teoretycznie wchodzi to w nieskończoną pętlę w podobny sposób, jak robi to podejście C ++ : metoda polimorficzna
y
jest tworzona w postaci instancji dla coraz bardziej skomplikowanych typów. W praktyce domyślny przydzielony rozmiar stosu szybko się przepełnia:Kredyty dla Luke'a Palmera .
źródło
Haskell (ghc), 32 + 2 = 34 bajty
biegać z
ghc -O <file>
. Wyzwala regułę przepisywania dla głównej funkcji, która przepisuje to samo. Jedyną niefortunną cechą jest to, że ghc jest wystarczająco inteligentny, aby to wykryć i zatrzymać po 100 iteracjach. Nie znam łatwego sposobu na wyłączenie tego zachowania.źródło
Boo, 25 bajtów
Definiuje to makro, które wykonuje się w czasie kompilacji, które wykonuje nieskończoną pętlę, a następnie wywołuje makro.
źródło
Rdza, 18 bajtów
Classic self-include. Rustc jest jednak denerwująco rozsądny i domyślnie ratuje się po 128 rekurencjach i rozszerza się na głębokość pierwszą, więc wykładniczy wzrost również nie działa. To samo dotyczy rozwiązań C i C ++.
źródło
Współczynnik ,
2916Część pomiędzy
<<
>>
jest wykonywana w czasie analizy.Co do tego
[ t ] loop
, co mogę zrobić, pozwolę ci zgadnąć ...Możesz umieścić to w Listener tak, jak jest, lub dodać do dowolnego pliku słownictwa lub skryptu z odpowiednimi dodatkami.
źródło
PHP, 19 bajtów
źródło