Profundidad máxima de recursión [cerrada]

15

¿Tu idioma tiene una profundidad de recursión máxima (MRD)?

Digamos que su idioma tiene MRD = 500

Escriba un código que encuentre la profundidad de recursión y genere el valor exacto

Para el caso anterior, su programa (o función) debería generar 500

Code-Golf ¡La respuesta más corta gana!


fuente
3
@cairdcoinheringaahing ... "que encuentra la profundidad de recursión" significa que la codificación no es válida
66
Creo que el principal problema con este desafío es que no está permitido imprimir un valor codificado, pero leer una variable de sistema codificada está bien. Los dos realmente no me parecen significativamente diferentes.
DJMcMayhem
2
Las incorporaciones de @DJMcMayhem muchas veces usan información codificada. Este desafío permite incorporaciones.
77
Sí, ese es mi punto. Ambos simplemente leen un valor codificado, pero uno está permitido y el otro no.
DJMcMayhem
3
@DJMcMayhem integrado en Mathica también puede tener la bandera suiza (he visto este desafío aquí), pero publicar la misma bandera que jpg no es válido.

Respuestas:

49

Mathematica, 15 bytes

$RecursionLimit

¯ \ _ (ツ) _ / ¯

Pruébalo en línea!

J42161217
fuente
17
¡Por supuesto que Mathematica tiene incorporado esto! +1
caird coinheringaahing
1
Tengo que amar Mathematica +1
JungHwan Min
Emacs Lisp en la misma línea (19): max-lisp-eval-depth
Caterpillar
19

Python 3 , 40 bytes

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

Pruébalo en línea!

Sin solo leerlo desde el builtin. Comenzamos en 2 en lugar de 1 porque la cláusula except se ejecuta un nivel antes de que ocurra un error. Este es un byte más corto en Python 2, por supuesto.

FryAmTheEggman
fuente
1
No necesita 3 bytes para llamar a f
8bitwide
Los envíos de @ 8bitwide como una función son aceptados por defecto. A menos que la pregunta los prohíba específicamente, puede enviar una función reutilizable como solución. Notarás que muchas otras respuestas a esta pregunta hacen lo mismo.
FryAmTheEggman
15

JavaScript (Babel) , 35 33 29 bytes

f=_=>do{try{-~f()}catch(e){}}
  • 2 bytes guardados gracias a Neil.

Pruébelo aquí , o use el fragmento a continuación para probarlo en evallugar de do.

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


Puerto Japt , 24 bytes

Realmente no vale la pena publicar esto como una solución separada, ya que es, esencialmente, idéntico.

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

Pruébalo


Explicación

JavaScript en sí mismo no tiene un límite de recursión per se, sino que el intérprete impone el límite (es decir, el navegador). ¡Qué bueno que definimos los idiomas por su intérprete aquí! Entre otros factores, el límite puede variar según el navegador y la memoria disponible, lo que se ve afectado por las operaciones que se realizan. El siguiente fragmento ilustra ese último punto, usando las 5 versiones diferentes de esta solución que pasé. Como puede ver en las últimas 2 pruebas, en Chrome, al menos, incluso el orden de las operaciones puede marcar la diferencia.

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}`))())

Dado eso, por lo tanto, no tenemos la conveniencia de una constante o método para trabajar. En cambio, vamos a crear una función que se llame a sí misma de forma continua antes, eventualmente, a la basura. En su forma más simple que es:

f=_=>f()

Pero eso no nos sirve para este desafío, ya que solo arroja un error de desbordamiento sin indicación de cuántas veces se fllamó a sí mismo. Podemos evitar el error trying a la llamada fde forma continua y catching cuando falla:

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

No hay error, pero aún no hay valor de retorno de cuántas veces la función logró llamarse a sí misma antes de fallar, porque en catchrealidad no está haciendo nada. Intentemos evaluar la try / catchdeclaración:

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

Ahora tenemos un valor que se devuelve (y, dado que se trata de un código de golf, nos ahorramos unos pocos bytes al usar un real return). Sin embargo, el valor que se devuelve es undefinednuevamente porque catchno está haciendo nada. Afortunadamente para nosotros -~undefined==1y -~n==n+1, por lo tanto, al abrir una -~llamada en frente de la llamada f, esencialmente tenemos -~-~ ... -~-~undefined, con otra -~antepuesta con cada llamada, dándonos la cantidad de veces que fse llamó.

f=_=>eval(`try{-~f()}catch(e){}`)
Lanudo
fuente
¡Buena solución, ya que asumo que no tienes acceso a una profundidad de recursión incorporada en JS!
Zacharý
3
33 bytes:f=_=>eval('try{-~f()}catch(e){}')
Neil
@Neil: Vi tu versión de 34 bytes cuando me iba a la cama y me pateé por no pensar en ello. Esa versión de 33 bytes está inspirada. Gracias.
Shaggy
13

Mathematica (no incorporado), 20 bytes

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

Omitir el ;cálculo 1+$IterationLimit(probablemente porque Mathematica optimiza la función de cola). Alternativamente, 0 //. x_ -> x + 1calcule ReplaceRepeatedel valor predeterminado MaxIteration, es decir, 65536(que es mayor que los dos valores anteriores).

(Este es un fragmento de código que evalúa el resultado. Sin embargo, la otra solución de Mathematica también lo es)

usuario202729
fuente
10

J, 8 bytes

1+$: ::]

Pruébalo en línea!

Por lo tanto, en realidad no sé cómo ejecutar un verbo sin ninguna entrada y una breve búsqueda (así como una intuición personal) hace que parezca que eso no es posible. Si es así, avíseme cómo hacerlo y eliminaré o actualizaré mi respuesta. Sin embargo, no tiene sentido que un verbo no tenga entrada. A la luz de esto, la función dada espera 0, la entrada predeterminada "vacía" para enteros. Probablemente pueda cambiarlo para usar la matriz vacía (0$0 ) si crees que es más apropiado.

Editar: el OP ha permitido que la función tome 0.

Explicación

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

Esto se llama a sí mismo de manera recursiva, agregando 1 a la entrada (se espera 0) hasta que llegue a un error de pila. Cuando se ]produce un error, llama a la adversa ( identidad correcta) en la entrada, que es solo 0.

Por cierto, el espacio es necesario .

col
fuente
1
salidas 6000 en mi máquina. fwiw creo que esto debería ser un juego justo, pero siempre se puede simplemente hacer que tu respuesta(1+$: ::]) 0
Jonás
@Jonah punto justo, estoy acostumbrado a enviar funciones. En mi máquina, es 6666 curiosamente.
cole
6660 en un iPad pro. ¡Frio!
Aganju
La forma en que maneja la máxima profundidad de recursión parece depender de la versión: en mi teléfono obtengo 5999 (que parece estar apagado en 1). En mi iPad (sinceramente, no recuerdo qué modelo), simplemente se bloquea.
cole
9

Python 3 , 41 32 bytes

import sys
sys.getrecursionlimit

Pruébalo en línea!

¡Guardado 9 bytes gracias a @FryAmTheEggman!

34 bytes

from sys import*
getrecursionlimit

35 bytes

__import__('sys').getrecursionlimit

Los últimos 2 son gracias a @totallyhuman

caird coinheringaahing
fuente
32 bytes , 34 bytes y 35 bytes . Elige tu opción. : P
totalmente humano
@FryAmTheEggman sí puedo, ¡gracias!
caird coinheringaahing
Recibo un error (en TIO, al menos) cuando intento ejecutar los primeros 2.
Shaggy
@Shaggy tendrá que intercambiar las líneas por la primera, la importación va después para permitir que se asigne un nombre al nombre incorporado. Actualizaré el enlace.
caird coinheringaahing
8

C (gcc, Linux x64), 180 133 bytes

-4 bytes gracias a @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)));}

Pruébalo en línea!

Instala un controlador SIGSEGV (señal 11) con una pila de señal alternativa (tamaño mínimo MINSIGSTKSZ es de 2 KB, el indicador SA_ONSTACKes 0x08000000), luego llama a una función sin argumentos y sin variables locales recursivamente hasta que la pila se desborda. Es interesante que la profundidad de recursión máxima varíe entre corridas, probablemente debido a ASLR.

La profundidad máxima de recursión en C depende de muchos factores, por supuesto. En un sistema Linux típico de 64 bits, el tamaño predeterminado de la pila es de 8 MB, y la alineación de la pila es de 16 bytes, por lo que obtiene una profundidad de recursión de aproximadamente 512K para funciones simples.

También tenga en cuenta que el programa anterior no funciona -O2debido a la optimización de llamadas de cola.

nwellnhof
fuente
1
+1! Puede guardar 4 bytes incrementando cy llamando exity sigactioncomo parámetros. Esto no hace una diferencia notable en el resultado: enlace TIO
scottinet
6

Java 8, 131 51 48 47 43 bytes

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

-80 bytes gracias a @Nevay . También probé un método en lugar de un programa, pero cometí un error y terminé con un programa completo. Ahora es un método.
-3 bytes gracias a @Neil haciendo uso de en finallylugar de catch(Error e).
-5 bytes gracias a @Nevay nuevamente.

Explicación:

Pruébalo aquí.

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
fuente
1
51 bytes:int c(){try{return-~c();}catch(Error e){return 1;}}
Nevay
2
@Nevay A menudo publicas excelentes respuestas en los comentarios. Puede publicarlos como respuestas y obtener algunas reputaciones. Nada prohíbe que una pregunta tenga varias respuestas Java. ;-)
Olivier Grégoire
2
int c(){int n=1;try{n=-~c();}finally{return n;}}ahorra 3 bytes pero me da una respuesta diferente?
Neil
2
47 bytes:int c(){int n=1;try{n+=c();}finally{return n;}}
Nevay
1
43 bytes:int d;int c(){try{c();}finally{return++d;}}
Nevay
4

Octava, 19 bytes

max_recursion_depth

Uso:

octave:1> max_recursion_depth
ans =  256
Ilya
fuente
4

R , 32 26 18 bytes

-8 bytes gracias a Sven Hohenstein : $hará una coincidencia parcial, por lo que podemos usar en explugar de la completa expressions.

cat(options()$exp)

El optionscomando también se puede utilizar para establecer la profundidad de recursión, es decir, options(expressions=500)para 500.

Pruébalo en línea!

Giuseppe
fuente
1
Puede guardar siete bytes eliminando ressionsdebido a una coincidencia parcial con $.
Sven Hohenstein
1
Más para referencia futura que como contribución; ¿Existe el consenso de que necesitas envolver esto en cat ()? R generará algo en la mayoría de las circunstancias, entonces, ¿hay alguna publicación que aclare las buenas prácticas / lógica a seguir?
CriminallyVulgar
@SvenHohenstein dang, siempre me olvido de eso después de escribir el código R con buen estilo ... ¡Gracias!
Giuseppe
1
@CriminallyVulgar vea, por ejemplo, esta publicación en meta; Ciertamente hay cierta incertidumbre al respecto.
Giuseppe
4

Octava , 25 22 20 bytes

2 bytes eliminados gracias a una sugerencia de Sanchises

@max_recursion_depth

Función anónima que genera el valor.

Pruébalo en línea!

Luis Mendo
fuente
No necesita (), ya max_recursion_depthque también es una función.
Sanchises
@Sanchises Gracias! Tienes razón: incluso si el documento dice que es una variable, en realidad es una función
Luis Mendo
Su edición ha convertido esto en un duplicado de la otra respuesta de Octave, por lo tanto, retenido @para mantenerla distinta (definiendo una función en lugar de REPL'ing el resultado).
Sanchises
@Sanchises En realidad, acabo de cambiar eso, aunque por una razón diferente (el código debería definir una función)
Luis Mendo
Sí, la otra respuesta es más como un programa; No estoy seguro de si eso realmente requeriría disp(lo habría incluido, pero esa es mi opinión personal sobre Octave REPL, y no estoy seguro de ningún meta consenso sobre eso)
Sanchises
3

zsh, 24 bytes

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

Pruébalo en línea! (Ver debajo de depuración)

bash, 24 bytes

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

Pruébalo en línea! (Ver debajo de depuración)

ksh93, 27 bytes

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

Pruébalo en línea! (Ver debajo de depuración)

guión, 27 bytes

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

Pruébalo en línea! (Excede la salida de depuración de tio, ejecútela en su propio shell)

Thor
fuente
1
¿Debería i=0y echono estar incluido en su conteo de bytes?
Shaggy
@ Shaggy: Tal vez, lo he cambiado a una solución más autónoma
Thor
1

Lua , 52 bytes

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

Pruébalo en línea!

Un taco
fuente
@ Shaggy en este caso sí, porque uso el nombre f. Si esto no fuera recursivo, podría salirse con la suya sin tenerlo
ATaco
Ah, no hizo lugar al fen pcall.
Shaggy
¿Por qué su programa se detiene en 200? aquí puede ver que en esa función simple va más allá de 200. Si quita la --puede confirmar que sigue siendo una llamada recursiva sin optimizaciones
Felipe Nardi Batista
1

q / kdb +, 16 bytes

Solución:

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

Ejemplo:

/ 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

Explicación:

Intente repetir, aumente x en uno cada vez, si hay un error, devuelva 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
callejero
fuente
1

Excel-VBA, 26 bytes

?Application.MaxIterations

No es la profundidad de recursión per-se, esto realmente genera el número máximo de iteraciones para una celda en una hoja de cálculo de Excel. Dado que el resultado pertenece a un idioma diferente al idioma en el que está escrito, quizás esto sea más apropiado:

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

Function f:f=Application.MaxIterations

Como eso se puede llamar desde una celda con

=f(

Para VBA sin incorporado:

Excel-VBA, 53 44 40 bytes

-9 como variable ya no necesita inicializarse o imprimirse

-4 ya que la ejecución del código ya no tiene que finalizar para evitar múltiples impresiones

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

Llame con s en la ventana inmediata, salidas a la celda A1 de la hoja de trabajo

(la advertencia tarda un tiempo en ejecutarse ahora, agregue Application.ScreenUpdating = Falseprimero)

Greedo
fuente
1

Lua , 45 37 bytes

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

Pruébalo en línea!

No sé con qué valor inicializar xya que no sé la cantidad de llamadas intermedias que hay ...

Felipe Nardi Batista
fuente
1

Clojure, 72 55 48 bytes

-23 bytes al deshacerse del átomo

-7 bytes gracias a @madstap. Cambió a usar fnover defy #(), y prover println.

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

Escribí y probé en mi teléfono. La aplicación Clojure REPL me dio una profundidad de 13087.

Solución básica Repetir hasta que se arroje un SO, incrementando un contador cada repetición. Cuando se lanza, se imprime el valor del contador.

Carcigenicate
fuente
Puede guardar 5 bytes utilizando en prlugar de println. También -2 bytes haciendo que el fn sea así: en ((fn f[x](,,,))0)lugar de (def f #(,,,))(f 0).
madstap
@madstap Gracias. Haré los cambios en un momento.
Carcigenicate
1

VBA, cualquier tipo, 41 39 bytes

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

Llame usando ?A()en la ventana Inmediato, o como función de hoja de trabajo.

Nota: Devuelve 4613 en Excel-VBA, mientras que la respuesta de @Greedo devuelve 3666 en mi sistema (el más alto debería ser el máximo). Aparentemente también varía entre los programas de Office (Access-VBA devuelve 4622, Word-VBA 4615)

Editar: Guess VBA agrega automáticamente las paréntesis, por lo que las eliminó.

Erik A
fuente
0

Pyth - 9 bytes

L.xyhbbyZ

Si puedo ejecutarlo como la respuesta J anterior, esto es de 7 bytes porque puedes sacar el último yZ.

Pruébelo en línea aquí .

Maltysen
fuente
55
Esto no funciona para mi. Fuera de línea, me sale un error de segmentación. En línea, no obtengo ningún resultado. No puedes atrapar un segfault.
isaacg
@isaacg espera, esto es realmente extraño. En línea, rara vez da 764, pero tienes razón la mayor parte del tiempo no da salida.
Maltysen
0

Adelante, 48 bytes

Bucles hasta que llega al límite.

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

Pruébalo en línea

mbomb007
fuente
0

Ruby, 39 bytes

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

Suprimir el mensaje de error es un poco más corto que rescatarlo, ya que de forma predeterminada rescue no se capturaSystemStackError .

Hay una respuesta más cursi si puedo mostrar en unario, representando n con n caracteres consecutivos de nueva línea:

Ruby, 35 bytes

$stderr=$<
f=->{puts;$.+=1;f[]}
f[]
histocrat
fuente
0

Gelatina , 18 bytes

:( *

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

Pruébalo en línea!

¿Cómo?

* Desde Jelly hasta donde yo sé:
(1) establece el límite de recursión de Python antes de configurar gran parte de su propio intérprete y analizar el código que se ejecutará; y
(2) no tiene forma de detectar errores de Python.
No estoy seguro de si hay una manera de evaluar de manera confiable el límite de recursión o imprimirlo, ya que se descubre, además de preguntarle a Python cuál fue el valor establecido ( ¡Me encantaría ver si se puede hacer!), Así que eso es lo que hace el código aquí:

“¡ż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
fuente