ภาษาของคุณมีความลึกในการเรียกซ้ำสูงสุด (MRD) หรือไม่?
สมมติว่าภาษาของคุณมีMRD = 500
เขียนรหัสที่ค้นหาความลึกของการสอบถามซ้ำและส่งออกค่าที่แน่นอน
สำหรับกรณีที่อยู่เหนือโปรแกรมของคุณ (หรือฟังก์ชั่น) ควรส่งออก500
คำตอบสั้น ๆ ของCode-Golfชนะ!
ภาษาของคุณมีความลึกในการเรียกซ้ำสูงสุด (MRD) หรือไม่?
สมมติว่าภาษาของคุณมีMRD = 500
เขียนรหัสที่ค้นหาความลึกของการสอบถามซ้ำและส่งออกค่าที่แน่นอน
สำหรับกรณีที่อยู่เหนือโปรแกรมของคุณ (หรือฟังก์ชั่น) ควรส่งออก500
คำตอบสั้น ๆ ของCode-Golfชนะ!
คำตอบ:
def f(x=2):
try:f(x+1)
except:print(x)
โดยไม่ต้องอ่านจาก builtin เราเริ่มต้นที่ 2 แทน 1 เพราะข้อยกเว้นมีการเรียกใช้หนึ่งระดับก่อนที่จะเกิดข้อผิดพลาด แน่นอนว่าเป็นไบต์ที่สั้นลงใน python 2
f=_=>do{try{-~f()}catch(e){}}
ลองได้ที่นี่หรือใช้โค้ดด้านล่างเพื่อทดสอบกับแทนevaldo
console.log((f=_=>eval(`try{-~f()}catch(e){}`))())
มันไม่คุ้มค่าที่จะโพสต์สิ่งนี้เป็นโซลูชันแยกต่างหากเนื่องจากเป็นหลักเหมือนกัน
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){}`)
f=_=>eval('try{-~f()}catch(e){}')
#0[#+1];&@1
%[[1,1]]
การละเว้น;จะคำนวณ1+$IterationLimit(อาจเป็นเพราะ Mathematica ปรับฟังก์ชั่นท้ายให้เหมาะสม) หรือ0 //. x_ -> x + 1คำนวณReplaceRepeatedค่าเริ่มต้นของMaxIterationซึ่งก็คือ65536(ซึ่งมากกว่าค่าทั้งสองด้านบน)
(นี่คือข้อมูลโค้ดที่ประเมินผลลัพธ์อย่างไรก็ตามโซลูชัน Mathematica อื่น ๆ ก็มีเช่นกัน)
1+$: ::]
ดังนั้นฉันไม่รู้จริง ๆ ว่าจะใช้คำกริยาอย่างไรโดยไม่มีการป้อนข้อมูลและการค้นหาสั้น ๆ (รวมถึงสัญชาติญาณส่วนตัว) ทำให้ดูเหมือนว่าเป็นไปไม่ได้ ถ้าเป็นโปรดแจ้งให้เราทราบวิธีการใช้และฉันจะลบหรืออัปเดตคำตอบของฉัน มันไม่สมเหตุสมผลเลยที่คำกริยาจะไม่ได้รับการป้อนข้อมูล ในแง่นี้ฟังก์ชั่นที่ได้รับคาดว่าจะ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 identity) บนอินพุตซึ่งเป็นเพียง 0
(1+$: ::]) 0
import sys
sys.getrecursionlimit
บันทึกแล้ว 9 ไบต์ขอบคุณ @FryAmTheEggman!
from sys import*
getrecursionlimit
__import__('sys').getrecursionlimit
2 สุดท้ายขอขอบคุณ @tallynhuman
-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)));}
ติดตั้งตัวจัดการ SIGSEGV (สัญญาณ 11) ด้วยสแต็กสัญญาณทางเลือก (ขนาดต่ำสุดMINSIGSTKSZคือ 2 KB, แฟล็กSA_ONSTACKล็กคือ 0x08000000) จากนั้นเรียกใช้ฟังก์ชันที่ไม่มีอาร์กิวเมนต์และไม่มีตัวแปรโลคัลซ้ำจนกระทั่งสแต็กล้น เป็นที่น่าสนใจว่าความลึกของการเรียกซ้ำสูงสุดนั้นแตกต่างกันไปตามการวิ่งอาจเป็นเพราะ ASLR
ความลึกการเรียกซ้ำสูงสุดใน C ขึ้นอยู่กับปัจจัยหลายอย่างแน่นอน บนระบบ Linux 64 บิตโดยทั่วไปขนาดสแต็กเริ่มต้นคือ 8 MB และการจัดเรียงสแต็กคือ 16 ไบต์ดังนั้นคุณจะได้ความลึกในการเรียกซ้ำประมาณ 512K สำหรับฟังก์ชั่นง่าย ๆ
นอกจากนี้โปรดทราบว่าโปรแกรมดังกล่าวไม่สามารถใช้งานได้-O2เนื่องจากการเพิ่มประสิทธิภาพการโทรหาง
int d;int c(){try{c();}finally{return++d;}}
-80 ไบต์ขอบคุณที่@Nevay ฉันลองใช้วิธีการแทนโปรแกรมเช่นกัน แต่ทำผิดพลาดลงเอยด้วยโปรแกรมเต็ม .. ตอนนี้เป็นวิธี
-3 ไบต์ขอบคุณที่@Neilโดยการใช้แทนfinally
-5 ไบต์ขอบคุณ@Nevaycatch(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
int c(){try{return-~c();}catch(Error e){return 1;}}
int c(){int n=1;try{n=-~c();}finally{return n;}}บันทึก 3 ไบต์ แต่ให้คำตอบที่ต่างออกไป
int c(){int n=1;try{n+=c();}finally{return n;}}
int d;int c(){try{c();}finally{return++d;}}
max_recursion_depth
การใช้งาน:
octave:1> max_recursion_depth
ans = 256
-8 ไบต์ขอบคุณที่สเวน Hohenstein : $จะทำจับคู่บางส่วนดังนั้นเราก็สามารถใช้แทนการเต็มรูปแบบexpexpressions
cat(options()$exp)
optionsคำสั่งนอกจากนี้ยังสามารถใช้ในการตั้งระดับความลึกเรียกซ้ำตัวเองคือoptions(expressions=500)500
ressions $
ลบออก 2 ไบต์ด้วยคำแนะนำของ Sanchises
@max_recursion_depth
ฟังก์ชั่นไม่ระบุชื่อที่ส่งออกค่า
()เพราะmax_recursion_depthเป็นฟังก์ชั่น
@จะเก็บไว้เพื่อให้แตกต่างกัน (การกำหนดฟังก์ชั่นแทนการ REPL
disp(ฉันจะรวมไว้ แต่นั่นเป็นความเห็นส่วนตัวของฉันเกี่ยวกับ Octave REPL และฉันไม่แน่ใจว่าฉันทามติ meta ใด ๆ เกี่ยวกับเรื่องนั้น)
f(){f $[++i];f};set -x;f
ลองออนไลน์! (ดูภายใต้การแก้ปัญหา)
f(){ f $[++i];};set -x;f
ลองออนไลน์! (ดูภายใต้การแก้ปัญหา)
f(){ f $(($1+1));};set -x;f
ลองออนไลน์! (ดูภายใต้การแก้ปัญหา)
f(){ f $(($1+1));};set -x;f
ลองออนไลน์! (มีเอาต์พุต debug เกิน tio, รันในเชลล์ของคุณเอง)
i=0และechoไม่รวมอยู่ในจำนวนไบต์ของคุณหรือไม่
f pcall
--คุณสามารถยืนยันได้ว่ามันยังคงเป็นสายเรียกซ้ำโดยไม่มีการเพิ่มประสิทธิภาพ
วิธีการแก้:
{@[.z.s;x+1;x]}0
ตัวอย่าง:
/ 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
คำอธิบาย:
พยายามเรียกคืนเพิ่ม x ทีละครั้งถ้าเกิดข้อผิดพลาดส่งคืน 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
?Application.MaxIterations
ไม่ใช่ความลึกในการเรียกซ้ำการเรียกซ้ำนี่จะแสดงจำนวนการทำซ้ำสูงสุดสำหรับเซลล์ในแผ่นงาน Excel เนื่องจากผลลัพธ์ที่เกี่ยวข้องกับภาษาอื่นนอกเหนือจากภาษาที่เขียนนี้อาจเป็นสิ่งที่เหมาะสมกว่า:
Function f:f=Application.MaxIterations
ตามที่สามารถเรียกได้จากเซลล์ด้วย
=f(
สำหรับ VBA ที่ไม่มีในตัว:
-9 เป็นตัวแปรไม่จำเป็นต้องเริ่มต้นหรือพิมพ์อีกต่อไป
-4 เนื่องจากการใช้รหัสไม่จำเป็นต้องสิ้นสุดเพื่อหลีกเลี่ยงการพิมพ์หลายครั้ง
Sub s:[A1]=[A1]+1:On Error Resume Next:s
โทรด้วย s ในหน้าต่างทันทีส่งออกไปยังเซลล์ A1 ของแผ่นงาน
(คำเตือนใช้เวลาสักครู่ในการทำงานตอนนี้เพิ่มApplication.ScreenUpdating = Falseก่อน)
x=2
f=load"x=x+1;f()"pcall(f)print(x)
ฉันไม่ทราบว่าจะเริ่มต้นxด้วยค่าใดเนื่องจากฉันไม่รู้จำนวนการโทรผ่านตัวกลางที่มี ...
-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.
pr instead of println. Also -2 bytes by making the fn like this: ((fn f[x](,,,))0) instead of (def f #(,,,))(f 0).
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.
L.xyhbbyZ
If I can run it like the J answer above, this is 7 bytes because you can take out the last yZ.
764, but you're right most of the time it gives no output.
Loops until it hits the limit.
: m 1+ recurse ;
: f 0 ['] m catch drop ; f .
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:
$stderr=$<
f=->{puts;$.+=1;f[]}
f[]
:( *
“¡żuẋ×HẒpƙ7"8!ƭ»ŒV
* 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