最大递归深度


15

您的语言是否具有最大递归深度(MRD)?

假设您的语言的MRD = 500

编写代码以找到递归深度并输出精确值

对于上述情况,您的程序(或函数)应输出500

打高尔夫球 最短答案胜出!


3
@cairdcoinheringaahing ...“找到递归深度”表示硬编码无效

6
我认为此挑战的主要问题是不允许打印硬编码的值,但是读取硬编码的系统变量就可以了。这两个对我来说似乎并没有太大的不同。
DJMcMayhem

2
内置的@DJMcMayhem多次使用硬编码信息。此挑战允许内置。

7
是的,这就是我的意思。他们俩都只是读取硬编码的值,但一个被允许,而另一个则不被允许。
DJMcMayhem

3
mathematica中内置的@DJMcMayhem也可以具有swiss标志(我在这里已经看到了这个挑战),但是张贴与jpg相同的标志是无效的。

Answers:



19

Python 3,40个字节

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

在线尝试!

不只是从内置文件中读取它。我们从2开始而不是1,因为except子句在错误发生之前运行了一层。当然,这在python 2中要短一个字节。


1
您是否不需要3个字节来调用f
8bitwide,

默认情况下,接受@ 8bitwide提交功能。除非问题明确禁止它们,否则您可以提交可复用功能作为解决方案。您会注意到,关于这个问题的许多其他答案也做同样的事情。
FryAmTheEggman'9

15

JavaScript(Babel)35 33 29字节

f=_=>do{try{-~f()}catch(e){}}
  • 感谢Neil,节省了2个字节。

在这里尝试,或使用下面的代码片段eval代替进行测试do

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


Japt端口,24字节

实际上,这是完全相同的,因此不值得将此作为单独的解决方案发布。

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

测试一下


说明

JavaScript本身本身没有递归限制,而是由解释器(即浏览器)强加了限制-很好的是,我们在这里通过其解释器来定义语言!在其他因素中,限制可能会因浏览器和可用内存而异,这受执行的操作影响。下面的代码片段使用我经历的5个不同版本的解决方案说明了最后一点。从最近的两次测试中可以看出,至少在Chrome中,即使操作顺序也会有所不同。

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

因此,我们就没有常量或方法的便利。取而代之的是,我们将创建一个函数,该函数在最终崩溃之前会不断进行自身调用。最简单的形式是:

f=_=>f()

但这对我们来说并没有太大用处,因为它只会抛出一个溢出错误,而不会表明f调用了多少次。我们可以通过tryingf连续调用并catch在失败时ing来避免错误:

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

没有错误,但是仍然没有返回该函数在失败之前成功调用自身多少次的返回值,因为该catch函数实际上并没有做任何事情。让我们尝试评估该try / catch语句:

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

现在,我们返回了一个值(并且由于这是代码高尔夫,因此使用了real节省了一些字节return)。但是,返回的值仍然是undefined,因为catch并未执行任何操作。幸运的是,我们-~undefined==1-~n==n+1所以,通过弹出一个-~呼叫的前面f,我们已经基本上得到了-~-~ ... -~-~undefined,另一个-~每次调用前置,给我们的次数f被调用。

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

好的解决方案,因为我假设您无法访问JS内置的递归深度!
扎卡里

3
33个字节:f=_=>eval('try{-~f()}catch(e){}')
尼尔(Neil)

@Neil:我上床时看到了您的34字节版本,并且因为不考虑而踢自己。33字节的版本受到启发。谢谢。
毛茸茸的

13

Mathematica(无内置),20字节

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

省略;将进行计算1+$IterationLimit(可能是因为Mathematica对函数进行了尾部优化)。或者,0 //. x_ -> x + 1计算ReplaceRepeated的default MaxIteration,即65536(大于上述两个值)。

(这是一个评估结果的代码段。但是,其他Mathematica解决方案也是)


10

J,8个字节

1+$: ::]

在线尝试!

因此,我实际上不知道如何在没有任何输入的情况下执行动词,并且进行简短的搜索(以及个人直觉)会使这看起来像是不可能的。如果是这样,请告诉我该怎么做,然后我将删除或更新我的答案。但是,不给动词输入没有任何意义。鉴于此,给定的函数Expects 0是整数的默认“空”输入。0$0如果您认为更合适,我可以将其更改为使用空数组()。

编辑:OP允许该函数取0。

说明

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

这将递归调用自身,在输入中加1(预期为0),直到遇到堆栈错误为止。当它出错时,它将]在输入上调用负数(-right标识),它仅为0。

顺便说一句,空间是必要的


1
在我的机器上输出6000。之前我认为这应该是公平的游戏,但是您始终可以做出自己的回答(1+$: ::]) 0
乔纳(Jonah)

@Jonah公平的观点,我习惯于提交功能。在我的机器上,奇怪的是6666。
科尔

iPad Pro上为6660。凉!
Aganju'9

它处理最大递归深度的方式似乎取决于版本-在我的手机上,我得到5999(似乎相差1)。在我的iPad上(老实说,我不记得哪个型号),它崩溃了。
科尔

9

Python 3中41 32个字节

import sys
sys.getrecursionlimit

在线尝试!

@FryAmTheEggman节省了9个字节!

34个字节

from sys import*
getrecursionlimit

35字节

__import__('sys').getrecursionlimit

最后2个感谢@totallyhuman



@FryAmTheEggman是的,我可以,谢谢!
caird coinheringaahing's

尝试运行第一个2时出现错误(至少在TIO上)
。– Shaggy

@Shaggy,您必须将第一个交换行,然后进行导入,以便为内置函数分配一个名称。我将更新链接。
caird coinheringaahing

8

C(GCC,Linux的X64),180个 133字节的

-4个字节,感谢@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)));}

在线尝试!

安装具有备用信号堆栈(最小大小MINSIGSTKSZ为2 KB,标志SA_ONSTACK为0x08000000)的SIGSEGV(信号11)处理程序,然后递归调用无参数且无局部变量的函数,直到堆栈溢出。有趣的是,最大递归深度可能会由于ASLR而在运行中有所不同。

当然,C语言中的最大递归深度取决于很多因素。在典型的64位Linux系统上,默认堆栈大小为8 MB,并且堆栈对齐为16个字节,因此对于简单功能,您获得的递归深度约为512K。

另请注意,-O2由于尾调用优化,以上程序无法使用。


1
+1!您可以通过递增c和调用exitand sigaction作为参数来节省4个字节。这不会在结果上产生显着差异:TIO链接
scottinet

6

Java 8,131 51 48 47 43字节

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

-80字节感谢@Nevay。我也尝试了方法而不是程序,但是犯了一个错误,所以最终得到了完整的程序。现在是方法。@Neil通过使用
-3个字节代替。 -5字节再次感谢@Nevayfinallycatch(Error e)

说明:

在这里尝试。

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

1
51个字节:int c(){try{return-~c();}catch(Error e){return 1;}}
Nevay

2
@Nevay您经常在评论中发布出色的答案。您可以将它们发布为答案,并获得一些声誉。没有什么问题可以提出几个Java答案。;-)
OlivierGrégoire17年

2
int c(){int n=1;try{n=-~c();}finally{return n;}}节省了3个字节,但给了我不同的答案?
尼尔

2
47个字节:int c(){int n=1;try{n+=c();}finally{return n;}}
Nevay

1
43个字节:int d;int c(){try{c();}finally{return++d;}}
Nevay

4

八度,19字节

max_recursion_depth

用法:

octave:1> max_recursion_depth
ans =  256

4

R32 26 18字节

感谢Sven Hohenstein,-8个字节$将进行部分匹配,因此我们可以使用exp而不是full expressions

cat(options()$exp)

options命令还可以用于设置递归深度,即为options(expressions=500)500。

在线尝试!


1
由于与的部分匹配,您可以通过删除来节省七个字节。ressions$
Sven Hohenstein'9

1
更多供将来参考,而不是作为贡献;您需要将其包装在cat()中的共识是什么?R 在大多数情况下会输出某些内容,因此是否在某处张贴了说明要遵循的良好做法/逻辑的文章?
刑事

@SvenHohenstein dang,在我以良好的风格编写R代码之后,我总是会忘记这一点……谢谢!
朱塞佩

1
@CriminallyVulgar例如在meta中看到这个帖子;肯定有一些不确定性。
朱塞佩

4

八度25 22 20字节

2 bytes removed thanks to a suggestion by Sanchises

@max_recursion_depth

Anonymous function that outputs the value.

Try it online!


You don't need the (), as max_recursion_depth is also a function.
Sanchises

@Sanchises Thanks! You are right: even if the doc says it's a variable, it's actually a function
Luis Mendo

Your edit has turned this in a duplicate of the other Octave answer, hence my retained @ to keep it distinct (defining a function rather than REPL'ing the result).
Sanchises

@Sanchises Actually I just changed that, although for a different reason (the code should actually define a function)
Luis Mendo

Yeah the other answer is more like a program; I'm not sure if that should actually require disp (I would have included it, but that's my personal opinion on Octave REPL, and I am not sure of any meta consensus on that)
Sanchises

3

zsh, 24 bytes

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

Try it online! (See under debug)

bash, 24 bytes

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

Try it online! (See under debug)

ksh93, 27 bytes

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

Try it online! (See under debug)

dash, 27 bytes

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

Try it online! (Exceeds tio debug output, run it in your own shell)


1
Should i=0 and the echo not be included in your byte count?
Shaggy

@Shaggy: Perhaps, I have changed it to a more self-contained solution
Thor

1

Lua, 52 bytes

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

Try it online!


@Shaggy in this case yes, because I use the name f. If this wasn't recursive I could get away with not having it
ATaco

Ah, I didn't spot the f in pcall.
Shaggy

why does your program stops at 200? here you can see that in that simple function it goes beyond 200. if you remove the -- you can confirm that it is still a recursive call with no optimizations
Felipe Nardi Batista

1

q/kdb+, 16 bytes

Solution:

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

Example:

/ 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

Explanation:

Try to recurse, increase x by one each time, if error, return 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

1

Excel-VBA, 26 Bytes

?Application.MaxIterations

Not recursion depth per-se, this actually outputs the maximum number of iterations for a cell in an Excel worksheet. Given that the output pertains to a language other than the language in which this is written, perhaps this is more appropriate:

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

Function f:f=Application.MaxIterations

As that can be called from a cell with

=f(

For VBA with no built in:

Excel-VBA, 53 44 40 bytes

-9 as variable no longer needs to be initialised or printed

-4 as code execution no longer has to be ended to avoid multiple prints

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

Call with s in the immediate window, outputs to cell A1 of the worksheet

(warning takes a while to run now, add Application.ScreenUpdating = False first)



1

Clojure, 72 55 48 bytes

-23 bytes by getting rid of the atom

-7 bytes thanks to @madstap. Switched to using fn over def and #(), and pr over println.

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

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.


You can save 5 bytes by using pr instead of println. Also -2 bytes by making the fn like this: ((fn f[x](,,,))0) instead of (def f #(,,,))(f 0).
madstap

@madstap Thanks. I'll make the changes in a bit.
Carcigenicate

1

VBA, any type, 41 39 bytes

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

Call 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.


0

Pyth - 9 bytes

L.xyhbbyZ

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.


5
This doesn't work for me. Offline, I get a segmentation fault. Online, I get no output at all. You can't catch a segfault.
isaacg

@isaacg wait this is really weird. Online, it rarely gives 764, but you're right most of the time it gives no output.
Maltysen




0

Ruby, 39 bytes

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

Suppressing the error message is a little shorter than rescuing it, since by default rescue doesn't catch SystemStackError.

There's a cheesier answer if I can output in unary, representing n with n consecutive newline characters:

Ruby, 35 bytes

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

0

Jelly, 18 bytes

:( *

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

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:

“¡ż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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.