Hat Ihre Sprache eine maximale Rekursionstiefe (MRD)?
Angenommen, Ihre Sprache hat MRD = 500
Schreiben Sie einen Code, der die Rekursionstiefe ermittelt und den genauen Wert ausgibt
Für den obigen Fall sollte Ihr Programm (oder Ihre Funktion) 500 ausgeben
Code-Golf Kürzeste Antwort gewinnt!
Antworten:
Mathematica, 15 Bytes
¯ \ _ (ツ) _ / ¯
Probieren Sie es online!
quelle
Python 3 , 40 Bytes
Probieren Sie es online!
Ohne es nur aus dem eingebauten zu lesen. Wir beginnen bei 2 statt bei 1, da die except-Klausel eine Ebene ausgeführt wird, bevor sie fehlerhaft ist. Dies ist natürlich ein Byte kürzer in Python 2.
quelle
JavaScript (Babel) ,
353329 BytesVersuchen Sie es hier , oder verwenden Sie das Snippet unten zu testen es mit
eval
stattdo
.Japt Port, 24 Byte
Es lohnt sich nicht, dies als separate Lösung zu veröffentlichen, da es im Wesentlichen identisch ist.
Probier es aus
Erläuterung
JavaScript selbst hat kein Rekursionslimit an sich, sondern das Limit wird vom Interpreter (dh dem Browser) auferlegt - gut, dass wir hier die Sprachen durch den Interpreter definieren! Unter anderem kann das Limit je nach Browser und verfügbarem Speicher variieren, was sich auf die ausgeführten Vorgänge auswirkt. Das folgende Snippet veranschaulicht diesen letzten Punkt anhand der 5 verschiedenen Versionen dieser Lösung, die ich durchlaufen habe. Wie Sie den letzten beiden Tests entnehmen können, kann zumindest in Chrome die Reihenfolge der Vorgänge einen Unterschied ausmachen.
Aus diesem Grund verfügen wir nicht über die Bequemlichkeit einer Konstante oder Methode, mit der wir arbeiten können. Stattdessen werden wir eine Funktion erstellen, die sich ständig selbst aufruft, bevor sie schließlich ausfällt. In seiner einfachsten Form ist das:
Aber das nützt uns nicht viel für diese Herausforderung, da es nur einen Überlauffehler auslöst, ohne dass angegeben wird, wie oft es sich
f
selbst angerufen hat. Wir können den Fehler vermeiden , indemtry
ing zu Anruff
kontinuierlich undcatch
ing , wenn es fehlschlägt:Kein Fehler, aber immer noch kein Rückgabewert dafür, wie oft die Funktion es geschafft hat, sich selbst aufzurufen, bevor ein Fehler auftrat, da sie
catch
eigentlich nichts unternimmt. Lassen Sie uns versuchen, dietry / catch
Anweisung zu bewerten :Jetzt wird ein Wert zurückgegeben (und da dies Codegolf ist, haben wir uns mit einem tatsächlichen Wert ein paar Bytes gespart
return
). Der zurückgegebene Wert ist jedoch wieder,undefined
weil dercatch
keine Aktion ausführt. Zum Glück für uns-~undefined==1
und-~n==n+1
so durch ein Aufspringen-~
vor dem Aufruff
haben wir im Wesentlichen bekommen-~-~ ... -~-~undefined
, mit einem anderen-~
bei jedem Aufruf vorangestellt, so dass die Anzahl der Zeitenf
genannt wurden.quelle
f=_=>eval('try{-~f()}catch(e){}')
Mathematica (nicht integriert), 20 Byte
Das Weglassen der
;
Berechnung wird1+$IterationLimit
(wahrscheinlich, weil Mathematica die Funktion schwanzoptimiert ). Alternativ können Sie auch die Standardeinstellung0 //. x_ -> x + 1
berechnen , d. H.ReplaceRepeated
MaxIteration
65536
(die größer ist als sowohl Wert ist oben).(Dies ist ein Code-Snippet, das als Ergebnis ausgewertet wird. Die andere Mathematica-Lösung ist es jedoch auch.)
quelle
J, 8 Bytes
Probieren Sie es online!
Ich weiß also nicht, wie man ein Verb ohne Eingabe ausführt, und eine kurze Suche (sowie eine persönliche Intuition) lässt es so scheinen, als wäre das nicht möglich. Wenn ja, lassen Sie es mich bitte wissen und ich werde meine Antwort entweder löschen oder aktualisieren. Es ist jedoch nicht sinnvoll, einem Verb keine Eingabe zu geben. In Anbetracht dessen erwartet die angegebene Funktion
0
die Standardeingabe "leer" für Ganzzahlen. Ich kann es wahrscheinlich ändern, um das leere Array zu verwenden (0$0
) zu verwenden, wenn Sie denken, dass das angemessener ist.Edit: Das OP hat der Funktion erlaubt, 0 zu nehmen.
Erläuterung
Dies ruft sich selbst rekursiv auf und addiert 1 zur Eingabe (0 wird erwartet), bis ein Stack-Fehler auftritt. Bei Fehlern wird die negative (
]
-right identity) für die Eingabe aufgerufen, die nur 0 ist.Der Platz ist übrigens notwendig .
quelle
(1+$: ::]) 0
Python 3 ,
4132 BytesProbieren Sie es online!
9 Bytes gespart dank @FryAmTheEggman!
34 Bytes
35 Bytes
Die letzten beiden sind @totallyhuman zu verdanken
quelle
C (gcc, Linux x64),
180133 Bytes-4 Bytes dank @scottinet
Probieren Sie es online!
Installiert einen SIGSEGV-Handler (Signal 11) mit einem alternativen Signalstapel (Mindestgröße
MINSIGSTKSZ
2 KB, FlagSA_ONSTACK
0x08000000) und ruft dann eine Funktion ohne Argumente und ohne lokale Variablen rekursiv auf, bis der Stapel überläuft. Es ist interessant, dass die maximale Rekursionstiefe über Läufe variiert, wahrscheinlich aufgrund von ASLR.Die maximale Rekursionstiefe in C hängt natürlich von vielen Faktoren ab. Auf einem typischen 64-Bit-Linux-System beträgt die Standard-Stack-Größe 8 MB und die Stack-Ausrichtung 16 Byte, sodass Sie für einfache Funktionen eine Rekursionstiefe von ca. 512 KB erhalten.
Beachten Sie auch, dass das obige Programm
-O2
aufgrund der Tail Call-Optimierung nicht funktioniert .quelle
c
und Aufrufen vonexit
undsigaction
als Parameter sparen . Das macht keinen nennenswerten Unterschied für das Ergebnis: TIO LinkJava 8,
13151484743 Bytes-80 Bytes dank @Nevay . Ich habe auch eine Methode anstelle eines Programms ausprobiert, habe aber einen Fehler gemacht und bin zu einem vollständigen Programm gekommen. Jetzt ist es eine Methode.
-3 Bytes dank @Neil unter Verwendung von
finally
anstelle voncatch(Error e)
.-5 byte danke nochmal an @Nevay .
Erläuterung:
Probieren Sie es hier aus.
quelle
int c(){try{return-~c();}catch(Error e){return 1;}}
int c(){int n=1;try{n=-~c();}finally{return n;}}
Speichert 3 Bytes, gibt mir aber eine andere Antwort?int c(){int n=1;try{n+=c();}finally{return n;}}
int d;int c(){try{c();}finally{return++d;}}
Oktave, 19 Bytes
Verwendung:
quelle
R ,
322618 Bytes-8 Bytes danke an Sven Hohenstein :
$
wird partiell abgleichen, also können wir einfachexp
anstelle des vollen verwendenexpressions
.Der
options
Befehl kann auch verwendet werden, um die Rekursionstiefe festzulegen, dhoptions(expressions=500)
für 500.Probieren Sie es online!
quelle
ressions
aufgrund einer teilweisen Übereinstimmung mit entfernen$
.Oktave ,
252220 Bytes2 Bytes entfernt dank eines Vorschlags von Sanchises
Anonyme Funktion, die den Wert ausgibt.
Probieren Sie es online!
quelle
()
, damax_recursion_depth
es auch eine Funktion ist.@
, um es eindeutig zu halten (indem ich eine Funktion definiere, anstatt das Ergebnis zu ERSETZEN).disp
(ich hätte es aufgenommen, aber das ist meine persönliche Meinung zu Octave REPL, und ich bin mir nicht sicher, ob dies einzsh, 24 bytes
Probieren Sie es online! (Siehe unter Debug)
Bash, 24 Bytes
Probieren Sie es online! (Siehe unter Debug)
ksh93, 27 bytes
Probieren Sie es online! (Siehe unter Debug)
Strich, 27 Bytes
Probieren Sie es online! (Übersteigt die Ausgabe von tio debug, führen Sie es in Ihrer eigenen Shell aus)
quelle
i=0
undecho
nicht in Ihrer Byteanzahl enthalten sein?Lua , 52 Bytes
Probieren Sie es online!
quelle
f
inpcall
.--
, können Sie bestätigen, dass es sich immer noch um einen rekursiven Aufruf ohne Optimierungen handeltq / kdb +, 16 Bytes
Lösung:
Beispiel:
Erläuterung:
Versuchen Sie, x jedes Mal um eins zu erhöhen. Wenn ein Fehler auftritt, geben Sie x zurück.
quelle
Excel-VBA, 26 Bytes
Hierbei wird nicht die Rekursionstiefe per se ausgegeben, sondern die maximale Anzahl von Iterationen für eine Zelle in einem Excel-Arbeitsblatt. Da sich die Ausgabe auf eine andere Sprache als die Sprache bezieht, in der dies geschrieben ist, ist dies möglicherweise angemessener:
Excel + Excel-Vba, 3 + 38 = 41 Bytes
Wie das aus einer Zelle mit aufgerufen werden kann
Für VBA ohne eingebautes:
Excel-VBA,
534440 Bytes-9 als Variable muss nicht mehr initialisiert oder gedruckt werden
-4, da die Codeausführung nicht mehr beendet werden muss, um Mehrfachdrucke zu vermeiden
Rufen Sie mit s im direkten Fenster auf und geben Sie es in Zelle A1 des Arbeitsblatts aus
(Warnung dauert eine Weile, bis sie ausgeführt wird.
Application.ScreenUpdating = False
Zuerst hinzufügen. )quelle
Lua ,
4537 BytesProbieren Sie es online!
Ich weiß nicht, mit welchem Wert
x
ich initialisieren soll, da ich nicht weiß, wie viele Zwischenrufe es gibt ...quelle
Clojure,
725548 Bytes-23 Bytes durch Entfernen des Atoms
-7 Bytes dank @madstap. Umgestellt auf die Verwendung von
fn
overdef
und#()
undpr
overprintln
.Schrieb und testete auf meinem Handy. Die Clojure REPL App gab mir eine Tiefe von 13087.
Grundlösung. Rekursieren Sie, bis ein SO ausgelöst wird, und erhöhen Sie bei jeder Rekursion einen Zähler. Wenn es geworfen wird, wird der Wert des Zählers gedruckt.
quelle
pr
anstelle von verwendenprintln
. Auch -2 Bytes, indem Sie die Fn wie folgt machen:((fn f[x](,,,))0)
statt(def f #(,,,))(f 0)
.VBA, beliebiger Typ,
41 bis39 ByteRufen Sie über
?A()
das Direktfenster oder als Arbeitsblattfunktion auf.Hinweis: Gibt in Excel-VBA 4613 zurück, während die Antwort von @Greedo auf meinem System 3666 zurückgibt (der höchste Wert sollte der Höchstwert sein). Offenbar variiert auch zwischen Office-Programmen (Access-VBA gibt 4622, Word-VBA 4615 zurück)
Bearbeiten: Vermutlich fügt VBA automatisch Klammern hinzu, entfernt sie also.
quelle
Pyth - 9 Bytes
Wenn ich es wie die J Antwort oben laufen lassen kann, ist dieses 7 Bytes, weil Sie das letzte herausnehmen können
yZ
.Probieren Sie es hier online aus .
quelle
764
, aber Sie haben die meiste Zeit Recht, es gibt keine Ausgabe.Viertens 48 Bytes
Schleifen, bis das Limit erreicht ist.
Probieren Sie es online aus
quelle
Tcl , 18 Bytes
Probieren Sie es online!
recursionlimit
kann abgekürzt werden mitr
Tcl , 31 Bytes
Probieren Sie es online!
quelle
Tcl , 49 Bytes
Probieren Sie es online!
quelle
Ruby, 39 Bytes
Das Unterdrücken der Fehlermeldung ist etwas kürzer als das Wiederherstellen, da sie standardmäßig
rescue
nicht abfängtSystemStackError
.Es gibt eine käsigere Antwort, wenn ich unärgerlich ausgeben kann und
n
n aufeinanderfolgende Zeilenumbrüche darstelle:Ruby, 35 Bytes
quelle
Gelee , 18 Bytes
:( *
Probieren Sie es online!
Wie?
* Soweit mir bekannt ist, seit Jelly:
(1) legt das Python-Rekursionslimit fest, bevor ein Großteil seines eigenen Interpreters eingerichtet und der auszuführende Code analysiert wird; und
(2) kann Python-Fehler
nicht abfangen. Ich bin mir nicht sicher, ob es eine Möglichkeit gibt, das Rekursionslimit entweder zuverlässig auszuwerten oder auszudrucken, wenn es entdeckt wird. Ich würde gerne sehen, ob das möglich ist!) So sieht der Code hier aus:
quelle