Czy twój język ma maksymalną głębokość rekurencji (MRD)?
Powiedzmy, że twój język ma MRD = 500
Napisz kod, który znajdzie głębokość rekurencji i wyświetli dokładną wartość
W powyższym przypadku twój program (lub funkcja) powinien wypisać 500
Code-Golf Najkrótsza odpowiedź wygrywa!
Odpowiedzi:
Mathematica, 15 bajtów
¯ \ _ (ツ) _ / ¯
Wypróbuj online!
źródło
Python 3 , 40 bajtów
Wypróbuj online!
Bez czytania tylko z wbudowanego. Zaczynamy od 2 zamiast 1, ponieważ klauzula wyjątku jest uruchamiana jeden poziom, zanim wystąpi błąd. Jest to oczywiście bajt krótszy w pythonie 2.
źródło
JavaScript (Babel) ,
353329 bajtówWypróbuj tutaj lub użyj Snippet poniżej, aby go przetestować
eval
zamiastdo
.Port Japt , 24 bajty
Naprawdę nie warto umieszczać tego jako osobnego rozwiązania, ponieważ jest to w zasadzie identyczne.
Sprawdź to
Wyjaśnienie
Sam JavaScript nie ma limitu rekurencji jako takiego, raczej jest narzucony przez tłumacza (tj. Przeglądarkę) - dobrze, że definiujemy języki przez ich tłumacza tutaj! Między innymi limit może się różnić w zależności od przeglądarki i dostępnej pamięci, na co mają wpływ wykonywane operacje. Poniższy fragment kodu ilustruje ten ostatni punkt, używając 5 różnych wersji tego rozwiązania, przez które przeszedłem. Jak widać z ostatnich 2 testów, w Chrome przynajmniej kolejność operacji może mieć znaczenie.
Biorąc to pod uwagę, dlatego nie mamy dogodności stałej lub metody do pracy. Zamiast tego stworzymy funkcję, która wywołuje się ciągle, zanim w końcu się wyłączy. W najprostszej formie to:
Ale to nie przydaje się nam w tym wyzwaniu, ponieważ generuje tylko błąd przepełnienia bez wskazania, ile razy się
f
nazywa. Możemy uniknąć błędu przeztry
ing, aby dzwonićf
ciągle icatch
ing, gdy się nie powiedzie:Bez błędu, ale wciąż brak wartości zwracanej ile razy funkcja zdołała się wywołać przed niepowodzeniem, ponieważ
catch
tak naprawdę nic nie robi. Spróbujmy ocenićtry / catch
stwierdzenie:Teraz zwracamy wartość (a ponieważ jest to golf golfowy, zaoszczędziliśmy kilka bajtów na faktycznym użyciu
return
). Zwracana jest jednak wartośćundefined
, ponieważcatch
nic nie robi. Na szczęście dla nas-~undefined==1
i-~n==n+1
dlatego, wysyłając-~
przed wezwaniem dof
, w zasadzie dostaliśmy-~-~ ... -~-~undefined
, z innym-~
poprzedzającym każde połączenie, podając liczbę wywołańf
.źródło
f=_=>eval('try{-~f()}catch(e){}')
Mathematica (bez wbudowanego), 20 bajtów
Pominięcie
;
obliczy1+$IterationLimit
(prawdopodobnie dlatego, że Mathematica optymalizuje ogon funkcji). Alternatywnie0 //. x_ -> x + 1
obliczReplaceRepeated
wartość domyślnąMaxIteration
, czyli65536
(która jest większa niż obie powyższe wartości).(Jest to fragment kodu, który ocenia wynik. Jednak inne rozwiązanie Mathematica również jest)
źródło
J, 8 bajtów
Wypróbuj online!
Tak więc, tak naprawdę nie wiem, jak wykonać czasownik bez wkładu, a krótkie wyszukiwanie (a także osobista intuicja) sprawia, że wydaje się to niemożliwe. Jeśli tak, daj mi znać, jak to zrobić, a ja usunę lub zaktualizuję swoją odpowiedź. Jednak nie ma sensu, aby czasownikowi nie podawano żadnych danych wejściowych. W świetle tego, podana funkcja oczekuje
0
, domyślnego „pustego” wejścia dla liczb całkowitych. Prawdopodobnie mogę to zmienić, aby użyć pustej tablicy (0$0
), jeśli uważasz, że to bardziej pasuje.Edycja: PO zezwolił tej funkcji na przyjęcie 0.
Wyjaśnienie
To wywołuje się rekurencyjnie, dodając 1 do wejścia (oczekiwane 0), aż napotka błąd stosu. Gdy
]
popełni błąd, wywołuje na wejściu wartość ujemną ( -prawą tożsamość), która wynosi tylko 0.Nawiasem mówiąc, przestrzeń jest niezbędna .
źródło
(1+$: ::]) 0
Python 3 ,
4132 bajtyWypróbuj online!
Zaoszczędź 9 bajtów dzięki @FryAmTheEggman!
34 bajty
35 bajtów
Ostatnie 2 są dzięki @totallyhuman
źródło
C (gcc, Linux x64),
180133 bajtów-4 bajty dzięki @scottinet
Wypróbuj online!
Instaluje moduł obsługi SIGSEGV (sygnał 11) z alternatywnym stosem sygnałów (minimalny rozmiar
MINSIGSTKSZ
to 2 KB, flagaSA_ONSTACK
to 0x08000000), a następnie wywołuje funkcję bez argumentów i rekurencyjnych zmiennych lokalnych, dopóki stos się nie przepełni. Interesujące jest to, że maksymalna głębokość rekurencji zmienia się w zależności od serii, prawdopodobnie z powodu ASLR.Oczywiście maksymalna głębokość rekurencji w C zależy od wielu czynników. W typowym 64-bitowym systemie Linux domyślny rozmiar stosu wynosi 8 MB, a wyrównanie stosu to 16 bajtów, dzięki czemu głębokość rekurencji wynosi około 512 KB dla prostych funkcji.
Pamiętaj również, że powyższy program nie działa
-O2
powodu optymalizacji wywołania ogona.źródło
c
i wywołującexit
orazsigaction
jako parametry. Nie robi to zauważalnej różnicy w wyniku: link TIOJava 8,
13151484743 bajtów-80 bajtów dzięki @Nevay . Próbowałem też metody zamiast programu, ale popełniłem błąd, więc otrzymałem pełny program. Teraz jest to metoda.
-3 bajty dzięki @Neil dzięki wykorzystaniu
finally
zamiastcatch(Error e)
.-5 bajtów dzięki @Nevay ponownie.
Wyjaśnienie:
Wypróbuj tutaj.
źródło
int c(){try{return-~c();}catch(Error e){return 1;}}
int c(){int n=1;try{n=-~c();}finally{return n;}}
oszczędza 3 bajty, ale daje inną odpowiedź?int c(){int n=1;try{n+=c();}finally{return n;}}
int d;int c(){try{c();}finally{return++d;}}
Oktawa, 19 bajtów
Stosowanie:
źródło
R ,
322618 bajtów-8 bajtów dzięki Svenowi Hohensteinowi :
$
częściowe dopasowanie, więc możemy po prostu użyćexp
zamiast pełnegoexpressions
.options
Komenda może być również używany do ustawiania głębokości rekurencji, to znaczy,options(expressions=500)
za 500.Wypróbuj online!
źródło
ressions
powodu częściowego dopasowania z$
.Oktawa ,
252220 bajtówUsunięto 2 bajty dzięki sugestii Sanchises
Anonimowa funkcja generująca wartość.
Wypróbuj online!
źródło
()
, ponieważmax_recursion_depth
jest to również funkcja.@
postanowiłem zachować jej odrębność (definiowanie funkcji zamiast REPL'owania wyniku).disp
(ja bym tozsh, 24 bajty
Wypróbuj online! (Patrz pod debugowaniem)
bash, 24 bajty
Wypróbuj online!(Patrz pod debugowaniem)
ksh93, 27 bajtów
Wypróbuj online!(Patrz pod debugowaniem)
myślnik, 27 bajtów
Wypróbuj online! (Przekracza wyjście debugowania tio, uruchom je we własnej powłoce)
źródło
i=0
iecho
nie mogą być uwzględnione w liczbie bajtów?Lua , 52 bajty
Wypróbuj online!
źródło
f
inpcall
.--
, możesz potwierdzić, że jest to połączenie rekurencyjne bez optymalizacjiq / kdb +, 16 bajtów
Rozwiązanie:
Przykład:
Wyjaśnienie:
Spróbuj powtórzyć, zwiększ x za każdym razem, jeśli błąd, zwróć x.
źródło
Excel-VBA, 26 bajtów
Nie sama głębokość rekurencji, w rzeczywistości wyświetla maksymalną liczbę iteracji dla komórki w arkuszu programu Excel. Biorąc pod uwagę, że dane wyjściowe dotyczą języka innego niż język, w którym jest napisany, być może jest to bardziej odpowiednie:
Excel + Excel-Vba, 3 + 38 = 41 bajtów
Jak to można wywołać z komórki za pomocą
W przypadku VBA bez wbudowanego:
Excel-VBA,
534440 bajtów-9, ponieważ zmienna nie musi już być inicjowana ani drukowana
-4, ponieważ wykonywanie kodu nie musi być zakończone, aby uniknąć wielu wydruków
Wywołaj za pomocą sz w bezpośrednim oknie, wyprowadza do komórki A1 arkusza
(uruchomienie ostrzeżenia zajmuje teraz chwilę, dodaj
Application.ScreenUpdating = False
najpierw)źródło
Lua ,
4537 bajtówWypróbuj online!
I don't know which value to initialize
x
with as I don't know the number of intermediary calls there are...źródło
Clojure,
725548 bytes-23 bytes by getting rid of the atom
-7 bytes thanks to @madstap. Switched to using
fn
overdef
and#()
, andpr
overprintln
.Wrote and tested on my phone. The Clojure REPL app gave me a depth of 13087.
Basic solution. Recurse until a SO is thrown, incrementing a counter each recurse. When it's thrown, the value of the counter is printed.
źródło
pr
instead ofprintln
. Also -2 bytes by making the fn like this:((fn f[x](,,,))0)
instead of(def f #(,,,))(f 0)
.VBA, any type,
4139 bytesCall using
?A()
in the Immediate window, or as worksheet function.Note: Returns 4613 in Excel-VBA, while the answer by @Greedo returns 3666 on my system (highest should be the max). Apparently also varies between Office programs (Access-VBA returns 4622, Word-VBA 4615)
Edit: Guess VBA auto-adds parantheses, so removed them.
źródło
Pyth - 9 bytes
If I can run it like the J answer above, this is 7 bytes because you can take out the last
yZ
.Try it online here.
źródło
764
, but you're right most of the time it gives no output.Forth, 48 bytes
Loops until it hits the limit.
Try it online
źródło
Tcl, 18 bytes
Try it online!
recursionlimit
can be abbreviated tor
Tcl, 31 bytes
Try it online!
źródło
Tcl, 49 bytes
Try it online!
źródło
Ruby, 39 bytes
Suppressing the error message is a little shorter than rescuing it, since by default
rescue
doesn't catchSystemStackError
.There's a cheesier answer if I can output in unary, representing
n
with n consecutive newline characters:Ruby, 35 bytes
źródło
Jelly, 18 bytes
:( *
Try it online!
How?
* Since Jelly as far as I am aware:
(1) sets the Python recursion limit prior to setting up much of its own interpreter and parsing the code to be run; and
(2) has no way of catching Python errors
I'm not sure if there is a way to either reliably evaluate the recursion limit or to print it out as it is discovered other than to actually ask Python what the value was set to (I'd love to see if it can be done though!) so that's what the code here does:
źródło