最大再帰深度[閉じた]


15

あなたの言語には最大再帰深度(MRD)がありますか?

あなたの言語がMRD = 500を持っているとしましょう

再帰の深さを見つけて正確な値を出力するコードを書く

上記の場合、プログラム(または関数)は500を出力するはずです

Code-Golf 最短回答が勝ちます!


3
@cairdcoinheringaahing ...ハードコーディングする手段「再帰の深さを発見することは、」無効です

6
この課題の主な問題は、ハードコードされた値の出力が許可されていないことですが、ハードコードされたシステム変数の読み取りは問題ないことです。この2つは、私にとってそれほど大きな違いはありません。
DJMcMayhem

2
@DJMcMayhemビルトインはハードコードされた情報を何度も使用します。この課題により、組み込みが可能になります。

7
はい、それが私のポイントです。どちらも単にハードコーディングされた値を読み取りますが、一方は許可され、もう一方は許可されません。
DJMcMayhem

3
数学に組み込まれている@DJMcMayhemにもスイスのフラグを付けることができます(ここでこの課題を見ました)が、jpgと同じフラグを投稿することは無効です。

回答:



19

Python 3、40バイト

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

オンラインでお試しください!

ビルトインから読むだけではありません。except節はエラーの1レベル前に実行されるため、1ではなく2から始めます。もちろん、これはPython 2では1バイト短くなっています。


1
fを呼び出すために3バイトを必要としないでください
8ビット幅

関数としての@ 8bitwideサブミッションはデフォルトで受け入れられます。質問で特に禁止されていない限り、再利用可能な機能をソリューションとして提出できます。この質問に関する他の多くの回答も同じことをしていることに気付くでしょう。
FryAmTheEggman

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つの異なるバージョンを使用して、最後のポイントを示しています。最後の2つのテストからわかるように、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自分自身が何回呼び出されたかを示すことなく、オーバーフローエラーをスローするだけなので、このチャレンジではあまり役に立ちません。エラーを回避tryするには、f連続して呼び出しcatch、失敗したときに呼び出します。

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

エラーはありませんが、catch実際には何も実行していないため、失敗する前に関数がそれ自体を呼び出した回数の戻り値はありません。try / catchステートメントを評価してみましょう:

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

これで値が返されます(これはコードゴルフであるため、実際のを使用するよりも数バイト節約できました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:寝る前に34バイトのバージョンを見たので、それを考えていないので自分を蹴りました。その33バイトバージョンはインスピレーションを受けています。ありがとう。
シャギー

13

Mathematica(組み込みなし)、20バイト

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

;計算を省略します1+$IterationLimit(おそらくMathematicaが関数をテール最適化するため)。または、のデフォルト、つまり(上記の両方の値よりも大きい)を0 //. x_ -> x + 1計算しReplaceRepeatedます。MaxIteration65536

(これは結果を評価するコードスニペットです。しかし、他のMathematicaソリューションもそうです)


10

J、8バイト

1+$: ::]

オンラインでお試しください!

そのため、入力なしで動詞を実行する方法が実際にはわからず、いくつかの簡単な検索(および個人的な直感)が不可能なように見えます。その場合は、その方法を教えてください。回答を削除または更新します。ただし、動詞に何も入力しないと意味がありません。これに照らして、与えられた関数は0、整数のデフォルトの「空の」入力であるexpectsを想定しています。おそらく空の配列を使用するように変更できます(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 identity)を呼び出しますが、これは0です。

By the way, the space is necessary.


1
outputs 6000 on my machine. fwiw i think this should be fair game, but you can always just make your answer (1+$: ::]) 0
Jonah

@Jonah fair point, I'm used to submitting functions. On my machine, it's 6666 oddly enough.
cole

6660 on an iPad pro. Cool!
Aganju

The way it handles maximum recursion depth seems version dependent -- on my phone I get 5999 (which appears to be off by 1). On my iPad (honestly I don't remember which model), it just crashes.
cole

9

Python 3, 41 32 bytes

import sys
sys.getrecursionlimit

Try it online!

Saved 9 bytes thanks to @FryAmTheEggman!

34 bytes

from sys import*
getrecursionlimit

35 bytes

__import__('sys').getrecursionlimit

The last 2 are thanks to @totallyhuman


32 bytes, 34 bytes and 35 bytes. Take your pick. :P
totallyhuman

@FryAmTheEggman yes I can, thank you!
caird coinheringaahing

I'm getting an error (on TIO, at least) when trying to run the first 2.
Shaggy

@Shaggy you'll have to swap the lines for the first one, the import goes after in order to allow the builtin to be allocated a name. I'll update the link.
caird coinheringaahing

8

C (gcc, Linux x64), 180 133 bytes

-4 bytes thanks to @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)));}

Try it online!

Installs a SIGSEGV (signal 11) handler with an alternate signal stack (minimum size MINSIGSTKSZ is 2 KB, flag SA_ONSTACK is 0x08000000), then calls a function without arguments and no local variables recursively until the stack overflows. It's interesting that the maximum recursion depth varies across runs, probably due to ASLR.

The maximum recursion depth in C depends on a lot of factors, of course. On a typical 64-bit Linux system the default stack size is 8 MB, and the stack alignment is 16 bytes, so you get a recursion depth of about 512K for simple functions.

Also note that the program above doesn't work with -O2 because of tail call optimization.


1
+1! You can save 4 bytes by incrementing c and calling exit and sigaction as parameters. This doesn't make a noticable difference on the result: TIO link
scottinet

6

Java 8, 131 51 48 47 43 bytes

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

-80 bytes thanks to @Nevay. I tried a method instead of program as well, but made a mistake so ended up with a full program.. Now it's a method.
-3 bytes thanks to @Neil by making use of finally instead of catch(Error e).
-5 byte thanks to @Nevay again.

Explanation:

Try it here.

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 bytes: int c(){try{return-~c();}catch(Error e){return 1;}}
Nevay

2
@Nevay You often post excellent answers in comments. You could post them as answers, and get some reputations. Nothing forbids any question from having several Java answers. ;-)
Olivier Grégoire

2
int c(){int n=1;try{n=-~c();}finally{return n;}} saves 3 bytes but gives me a different answer?
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

Octave, 19 bytes

max_recursion_depth

Usage:

octave:1> max_recursion_depth
ans =  256

4

R, 32 26 18 bytes

-8 bytes thanks to Sven Hohenstein : $ will do partial matching, so we can just use exp instead of the full expressions.

cat(options()$exp)

The options command can also be used to set the recursion depth, i.e., options(expressions=500) for 500.

Try it online!


1
You can save seven bytes by removing ressions due to partial matching with $.
Sven Hohenstein

1
More for future reference than as a contribution; is the consensus that you need to wrap this in cat()? R will output something in most circumstances, so is there a post somewhere clarifying good practice/logic to follow?
CriminallyVulgar

@SvenHohenstein dang, I always forget about that after I write R code in good style...Thank you!
Giuseppe

1
@CriminallyVulgar see for instance this post in meta; there's certainly some uncertainty about it.
Giuseppe

4

Octave, 25 22 20 bytes

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.