Profondeur de récursivité maximale [fermé]

15

Votre langue a-t-elle une profondeur de récursivité maximale (MRD)?

Disons que votre langue a MRD = 500

Écrivez un code qui trouve la profondeur de récursivité et génère la valeur exacte

Pour le cas ci-dessus, votre programme (ou fonction) devrait produire 500

Code-Golf La réponse la plus courte gagne!


la source
3
@cairdcoinheringaahing ... "qui trouve la profondeur de récursivité" signifie que le codage en dur n'est pas valide
6
Je pense que le principal problème avec ce défi est que l'impression d'une valeur codée en dur n'est pas autorisée, mais la lecture d'une variable système codée en dur est très bien. Les deux ne me semblent pas vraiment différents.
DJMcMayhem
2
@DJMcMayhem intégré utilise souvent des informations codées en dur. Ce défi permet des intégrés.
7
Oui, c'est mon point. Ils lisent tous deux simplement une valeur codée en dur, mais l'un est autorisé et l'autre ne l'est pas.
DJMcMayhem
3
@DJMcMayhem intégré dans Mathemica peut également avoir le drapeau suisse (j'ai vu ce défi ici), mais publier le même drapeau que jpg n'est pas valide.

Réponses:

49

Mathematica, 15 octets

$RecursionLimit

¯ \ _ (ツ) _ / ¯

Essayez-le en ligne!

J42161217
la source
17
Bien sûr, Mathematica a intégré cela! +1
caird coinheringaahing
1
Je dois aimer Mathematica +1
JungHwan Min
Emacs Lisp dans la même veine (19): max-lisp-eval-depth
Caterpillar
19

Python 3 , 40 octets

def f(x=2):
 try:f(x+1)
 except:print(x)

Essayez-le en ligne!

Sans simplement le lire depuis le builtin. Nous commençons à 2 au lieu de 1 parce que la clause except est exécutée un niveau avant qu'elle ne génère d'erreurs. C'est un octet plus court en python 2, bien sûr.

FryAmTheEggman
la source
1
N'avez-
Les soumissions @ 8bitwide en tant que fonction sont acceptées par défaut. À moins que la question ne les interdise spécifiquement, vous pouvez soumettre une fonction réutilisable comme solution. Vous remarquerez que de nombreuses autres réponses à cette question font la même chose.
FryAmTheEggman
15

JavaScript (Babel) , 35 33 29 octets

f=_=>do{try{-~f()}catch(e){}}
  • 2 octets enregistrés grâce à Neil.

Essayez-le ici ou utilisez l'extrait ci-dessous pour le tester avec evalau lieu de do.

console.log((f=_=>eval(`try{-~f()}catch(e){}`))())


Port Japt , 24 octets

Cela ne vaut pas vraiment la peine d'être publié comme une solution distincte car elle est essentiellement identique.

Ox`try\{-~rp()}¯t®(e)\{}

Essaye-le


Explication

JavaScript lui-même n'a pas de limite de récursivité en soi, mais la limite est imposée par l'interpréteur (c'est-à-dire le navigateur) - c'est une bonne chose que nous définissions les langues par leur interprète ici! Entre autres facteurs, la limite peut varier selon le navigateur et la mémoire disponible, ce qui est affecté par les opérations effectuées. L'extrait suivant illustre ce dernier point, en utilisant les 5 versions différentes de cette solution que j'ai utilisées. Comme vous pouvez le voir sur les 2 derniers tests, dans Chrome, au moins, même l'ordre des opérations peut faire la différence.

console.log((f=(i=0)=>eval(`try{f(i+1)}catch(e){i}`))())
console.log((f=i=>eval(`try{f(-~i)}catch(e){i}`))())
console.log((f=(i=0)=>eval(`try{f(++i)}catch(e){i}`))())
console.log((f=_=>eval(`try{-~f()}catch(e){}`))())
console.log((f=_=>eval(`try{f()+1}catch(e){0}`))())
console.log((f=_=>eval(`try{1+f()}catch(e){0}`))())

Compte tenu de cela, nous n'avons donc pas la commodité d'une constante ou d'une méthode avec laquelle travailler. Au lieu de cela, nous allons créer une fonction qui s'appelle elle-même en continu avant, éventuellement, de craquer. Dans sa forme la plus simple qui soit:

f=_=>f()

Mais cela ne nous est pas très utile pour ce défi car il ne génère qu'une erreur de débordement sans indication du nombre de fois où il s'est fappelé. Nous pouvons éviter l'erreur en trying à l' appel en fcontinu et catching quand il échoue:

f=_=>{try{f()}catch(e){}}

Aucune erreur, mais toujours pas de valeur de retour du nombre de fois où la fonction a réussi à s'appeler avant d'échouer, car le catchne fait rien. Essayons d'évaluer l' try / catchénoncé:

f=_=>eval(`try{f()}catch(e){}`)

Maintenant, nous avons une valeur renvoyée (et, comme il s'agit du code golf, nous nous sommes épargnés de quelques octets en utilisant un réel return). La valeur renvoyée, cependant, l'est undefinedencore parce que le catchne fait rien. Heureusement pour nous -~undefined==1et -~n==n+1donc, en passant un -~devant l'appel f, nous avons essentiellement -~-~ ... -~-~undefined, avec un autre -~ajouté à chaque appel, nous indiquant le nombre de fois où il a fété appelé.

f=_=>eval(`try{-~f()}catch(e){}`)
Hirsute
la source
Belle solution, car je suppose que vous n'avez pas accès à une profondeur de récurrence intégrée dans JS!
Zacharý
3
33 octets:f=_=>eval('try{-~f()}catch(e){}')
Neil
@Neil: J'ai vu votre version de 34 octets alors que j'allais me coucher et me suis donné un coup de pied pour ne pas y avoir pensé. Cette version de 33 octets est inspirée. Merci.
Shaggy
13

Mathematica (pas intégré), 20 octets

#0[#+1];&@1
%[[1,1]]

Omettre le ;calculera 1+$IterationLimit(probablement parce que Mathematica optimise la fonction). Vous pouvez également 0 //. x_ -> x + 1calculer ReplaceRepeatedla valeur par défaut MaxIteration, c'est-à-dire 65536(qui est supérieure à la valeur ci-dessus).

(Il s'agit d'un extrait de code qui évalue le résultat. Cependant, l'autre solution Mathematica l'est également)

user202729
la source
10

J, 8 octets

1+$: ::]

Essayez-le en ligne!

Donc, je ne sais pas vraiment comment exécuter un verbe sans aucune entrée et une brève recherche (ainsi qu'une intuition personnelle) donne l'impression que ce n'est pas possible. Si c'est le cas, faites-le moi savoir et je supprimerai ou mettrai à jour ma réponse. Cela n'a pas vraiment de sens de ne pas donner d'entrée à un verbe. À la lumière de cela, la fonction donnée attend 0, l'entrée "vide" par défaut pour les entiers. Je peux probablement le changer pour utiliser le tableau vide ( 0$0) si vous pensez que cela convient mieux.

Edit: l'OP a permis à la fonction de prendre 0.

Explication

1+$: ::]
     ::]  Assign adverse: if an error occurs, call ] (the identify function)
1+        Add one to
  $:      Recursive call to self

Cela s'appelle récursivement, en ajoutant 1 à l'entrée (0 attendu) jusqu'à ce qu'il rencontre une erreur de pile. Lorsqu'il commet une erreur, il appelle le contraire (] opposé -droite identité) sur l'entrée, qui est juste 0.

À propos, l'espace est nécessaire .

cole
la source
1
sorties 6000 sur ma machine. fwiw je pense que cela devrait être juste, mais vous pouvez toujours faire votre réponse(1+$: ::]) 0
Jonah
@Jonah fair point, j'ai l'habitude de soumettre des fonctions. Sur ma machine, c'est 6666 assez curieusement.
cole
6660 sur un iPad pro. Cool!
Aganju
La façon dont il gère la profondeur de récursivité maximale semble dépendre de la version - sur mon téléphone, j'obtiens 5999 (qui semble être désactivé par 1). Sur mon iPad (honnêtement, je ne me souviens pas quel modèle), il se bloque simplement.
cole
9

Python 3 , 41 32 octets

import sys
sys.getrecursionlimit

Essayez-le en ligne!

9 octets enregistrés grâce à @FryAmTheEggman!

34 octets

from sys import*
getrecursionlimit

35 octets

__import__('sys').getrecursionlimit

Les 2 derniers grâce à @totallyhuman

caird coinheringaahing
la source
32 octets , 34 octets et 35 octets . Faites votre choix. : P
totalement humain
@FryAmTheEggman oui je peux, merci!
caird coinheringaahing
Je reçois une erreur (sur TIO, au moins) lorsque j'essaie d'exécuter le premier 2.
Shaggy
@Shaggy vous devrez échanger les lignes pour la première, l'importation se poursuit afin de permettre à la fonction interne de se voir attribuer un nom. Je mettrai à jour le lien.
caird coinheringaahing
8

C (gcc, x64 Linux), 180 133 bytes

-4 octets grâce à @scottinet

c;f(){f(++c);}h(){exit(printf("%d",c));}main(){int b[512];f(sigaction(11,(int*[]){h,[17]=1<<27},sigaltstack((int*[]){b,0,2048},0)));}

Essayez-le en ligne!

Installe un gestionnaire SIGSEGV (signal 11) avec une autre pile de signaux (la taille minimale MINSIGSTKSZest de 2 Ko, l'indicateur SA_ONSTACKest 0x08000000), puis appelle une fonction sans arguments et sans variables locales récursivement jusqu'à ce que la pile déborde. Il est intéressant de noter que la profondeur de récursivité maximale varie d'une série à l'autre, probablement en raison de l'ASLR.

La profondeur de récursivité maximale en C dépend bien sûr de nombreux facteurs. Sur un système Linux 64 bits typique, la taille de pile par défaut est de 8 Mo et l'alignement de la pile est de 16 octets, vous obtenez donc une profondeur de récursivité d'environ 512 Ko pour les fonctions simples.

Notez également que le programme ci-dessus ne fonctionne pas en -O2raison de l'optimisation des appels de queue.

nwellnhof
la source
1
+1! Vous pouvez enregistrer 4 octets en incrémentant cet en appelant exitet en sigactiontant que paramètres. Cela ne fait aucune différence notable sur le résultat: lien TIO
scottinet
6

Java 8, 131 51 48 47 43 octets

int d;int c(){try{c();}finally{return++d;}}

-80 octets grâce à @Nevay . J'ai aussi essayé une méthode au lieu d'un programme, mais j'ai fait une erreur, donc j'ai fini avec un programme complet. Maintenant c'est une méthode.
-3 octets grâce à @Neil en utilisant finallyau lieu de catch(Error e).
-5 octets grâce à @Nevay .

Explication:

Essayez-le ici.

int d;                 // Depth-integer `d` on class-level (implicit 0)
int c(){               // Method without parameter and integer return-type
  try{c();}            //  Recursive call
  finally{return++d;}  //  Increase depth-integer `d` and always return it,
                       //   whether a StackOverflowError occurs or not
}                      // End of method
Kevin Cruijssen
la source
1
51 octets:int c(){try{return-~c();}catch(Error e){return 1;}}
Nevay
2
@Nevay Vous postez souvent d'excellentes réponses dans les commentaires. Vous pouvez les publier comme réponses et obtenir des réputations. Rien n'interdit à toute question d'avoir plusieurs réponses Java. ;-)
Olivier Grégoire
2
int c(){int n=1;try{n=-~c();}finally{return n;}}enregistre 3 octets mais me donne une réponse différente?
Neil
2
47 octets:int c(){int n=1;try{n+=c();}finally{return n;}}
Nevay
1
43 octets:int d;int c(){try{c();}finally{return++d;}}
Nevay
4

Octave, 19 octets

max_recursion_depth

Usage:

octave:1> max_recursion_depth
ans =  256
Il y a
la source
4

R , 32 26 18 octets

-8 octets grâce à Sven Hohenstein : $fera une correspondance partielle, donc nous pouvons simplement utiliser à la expplace du plein expressions.

cat(options()$exp)

La optionscommande peut également être utilisée pour définir la profondeur de récursivité, c'est-à-dire options(expressions=500)pour 500.

Essayez-le en ligne!

Giuseppe
la source
1
Vous pouvez enregistrer sept octets en les supprimant en ressionsraison d'une correspondance partielle avec $.
Sven Hohenstein
1
Plus pour référence future que comme contribution; est le consensus que vous devez envelopper dans cat ()? R produira quelque chose dans la plupart des circonstances, donc y a-t-il un article clarifiant les bonnes pratiques / la logique à suivre?
CriminallyVulgar
@SvenHohenstein dang, j'oublie toujours cela après avoir écrit le code R dans le bon style ... Merci!
Giuseppe
1
@CriminallyVulgar voir par exemple ce post dans meta; il y a certainement une certaine incertitude à ce sujet.
Giuseppe
4

Octave , 25 22 20 octets

2 octets supprimés grâce à une suggestion de Sanchises

@max_recursion_depth

Fonction anonyme qui génère la valeur.

Essayez-le en ligne!

Luis Mendo
la source
Vous n'avez pas besoin de (), comme max_recursion_depthc'est aussi une fonction.
Sanchises
@Sanchises Merci! Vous avez raison: même si le doc dit que c'est une variable, c'est en fait une fonction
Luis Mendo
Votre modification a transformé cela en un double de l'autre réponse Octave, d'où ma retenue @pour la garder distincte (définir une fonction plutôt que de RÉPLIQUER le résultat).
Sanchises
@Sanchises En fait, je viens de changer cela, bien que pour une raison différente (le code devrait en fait définir une fonction)
Luis Mendo
Oui, l'autre réponse ressemble plus à un programme; Je ne sais pas si cela devrait réellement nécessiter disp(je l'aurais inclus, mais c'est mon opinion personnelle sur Octave REPL, et je ne suis pas sûr d'un méta consensus à ce sujet)
Sanchises
3

zsh, 24 octets

f(){f $[++i];f};set -x;f

Essayez-le en ligne! (Voir sous débogage)

bash, 24 octets

f(){ f $[++i];};set -x;f

Essayez-le en ligne! (Voir sous débogage)

ksh93, 27 octets

f(){ f $(($1+1));};set -x;f

Essayez-le en ligne! (Voir sous débogage)

tiret, 27 octets

f(){ f $(($1+1));};set -x;f

Essayez-le en ligne! (Dépasse la sortie de débogage de tio, exécutez-le dans votre propre shell)

Thor
la source
1
Doit i=0et echone doit pas être inclus dans votre nombre d'octets?
Shaggy
@Shaggy: Peut-être que je l'ai changé pour une solution plus autonome
Thor
1

Lua , 52 octets

f=load"b,e=pcall(f,(...or 3)+1)return b and e or..."

Essayez-le en ligne!

ATaco
la source
@Shaggy dans ce cas oui, car j'utilise le nom f. Si ce n'était pas récursif, je pourrais m'en tirer sans l'avoir
ATaco
Ah, je ne l' ai pas repérer les fdans pcall.
Shaggy
pourquoi votre programme s'arrête à 200? ici, vous pouvez voir que dans cette fonction simple, il dépasse 200. si vous supprimez le, --vous pouvez confirmer qu'il s'agit toujours d'un appel récursif sans optimisation
Felipe Nardi Batista
1

q / kdb +, 16 octets

Solution:

{@[.z.s;x+1;x]}0

Exemple:

/ solution
q){@[.z.s;x+1;x]}0
2000

/ without apply (try/catch)
q){.z.s x+1}0
'stack
@
{.z.s x+1}
2001

Explication:

Essayez de reprendre, augmentez x de un à chaque fois, si erreur, retournez x.

{@[.z.s;x+1;x]}0 / the solution
{             }0 / call lambda function with 0
 @[    ;   ; ]   / @[function;argument;catch]
   .z.s          / call self (ie recurse)
        x+1      / increment x
            x    / return x if function returns error
streetster
la source
1

Excel-VBA, 26 octets

?Application.MaxIterations

Pas la profondeur de récursivité en soi, cela génère en fait le nombre maximal d'itérations pour une cellule dans une feuille de calcul Excel. Étant donné que la sortie se rapporte à une langue autre que la langue dans laquelle cela est écrit, c'est peut-être plus approprié:

Excel + Excel-Vba, 3 + 38 = 41 octets

Function f:f=Application.MaxIterations

Comme cela peut être appelé depuis une cellule avec

=f(

Pour VBA sans intégré:

Excel-VBA, 53 44 40 octets

-9 car la variable n'a plus besoin d'être initialisée ou imprimée

-4 car l'exécution du code ne doit plus être terminée pour éviter les impressions multiples

Sub s:[A1]=[A1]+1:On Error Resume Next:s

Appelez avec s dans la fenêtre immédiate, affiche la cellule A1 de la feuille de calcul

(l'avertissement prend un certain temps pour s'exécuter maintenant, ajoutez d' Application.ScreenUpdating = Falseabord)

Greedo
la source
1

Lua , 45 37 octets

x=2
f=load"x=x+1;f()"pcall(f)print(x)

Essayez-le en ligne!

Je ne sais pas avec quelle valeur initialiser xcar je ne connais pas le nombre d'appels intermédiaires ...

Felipe Nardi Batista
la source
1

Clojure, 72 55 48 octets

-23 octets en se débarrassant de l'atome

-7 octets grâce à @madstap. Passé à l'utilisation de fnover defet #(), and prover println.

((fn f[i](try(f(inc i))(catch Error e(pr i))))0)

Écrit et testé sur mon téléphone. L'application Clojure REPL m'a donné une profondeur de 13087.

Solution basique. Réexaminez jusqu'à ce qu'un SO soit lancé, en incrémentant un compteur à chaque récursif. Lorsqu'il est lancé, la valeur du compteur est imprimée.

Carcigenicate
la source
Vous pouvez enregistrer 5 octets en utilisant prau lieu de println. Aussi -2 octets en faisant le fn comme ceci: ((fn f[x](,,,))0)au lieu de (def f #(,,,))(f 0).
madstap
@madstap Merci. Je ferai les changements dans un instant.
Carcigenicate
1

VBA, tout type, 41 39 octets

Function A:On Error Resume Next:A=A()+1

Appelez en utilisant ?A()dans la fenêtre Exécution ou en tant que fonction de feuille de calcul.

Remarque: Renvoie 4613 dans Excel-VBA, tandis que la réponse de @Greedo renvoie 3666 sur mon système (le plus élevé devrait être le maximum). Apparemment, varie également entre les programmes Office (Access-VBA renvoie 4622, Word-VBA 4615)

Edit: Devinez VBA ajoute automatiquement des parenthèses, alors supprimez-les.

Erik A
la source
0

Pyth - 9 octets

L.xyhbbyZ

Si je peux l'exécuter comme la réponse J ci-dessus, c'est 7 octets car vous pouvez supprimer le dernier yZ.

Essayez-le en ligne ici .

Maltysen
la source
5
Ça ne marche pas pour moi. Hors ligne, je reçois un défaut de segmentation. En ligne, je ne reçois aucune sortie. Vous ne pouvez pas attraper une faute de segmentation.
isaacg
@isaacg attend, c'est vraiment bizarre. En ligne, il donne rarement 764, mais vous avez raison la plupart du temps, il ne donne aucune sortie.
Maltysen
0

Forth, 48 octets

Boucles jusqu'à ce qu'il atteigne la limite.

: m 1+ recurse ;
: f 0 ['] m catch drop ; f .

Essayez-le en ligne

mbomb007
la source
0

Rubis, 39 octets

END{p$.}
$stderr=$<
f=->{$.+=1;f[]}
f[]

La suppression du message d'erreur est un peu plus courte que le sauvetage, car par défaut rescue il ne prend pasSystemStackError .

Il y a une réponse plus ringarde si je peux produire en unaire, représentant n avec n caractères de nouvelle ligne consécutifs:

Rubis, 35 octets

$stderr=$<
f=->{puts;$.+=1;f[]}
f[]
histocrate
la source
0

Gelée , 18 octets

:( *

“¡żuẋ×HẒpƙ7"8!ƭ»ŒV

Essayez-le en ligne!

Comment?

* Depuis Jelly pour autant que je sache:
(1) définit la limite de récursivité Python avant de configurer une grande partie de son propre interpréteur et d'analyser le code à exécuter; et
(2) n'a aucun moyen d'attraper les erreurs Python,
je ne suis pas sûr s'il existe un moyen d'évaluer de manière fiable la limite de récursivité ou de l'imprimer lorsqu'elle est découverte autrement que de demander à Python quelle valeur a été définie ( J'aimerais voir si cela peut être fait!), C'est donc ce que fait le code ici:

“¡żuẋ×HẒpƙ7"8!ƭ»ŒV - Link: no arguments
“¡żuẋ×HẒpƙ7"8!ƭ»   - compression of "sys."+"get"+"recursion"+"limit"+"()"
                ŒV - evaluate as Python code
Jonathan Allan
la source