Pure Evil: Eval
a=lambda x,y:(y<0)*x or eval("a("*9**9**9+"x**.1"+",y-1)"*9**9**9)
print a(input(),9**9**9**9**9)//1
คำสั่งภายใน EVAL สร้างสตริงที่มีความยาว 7 * a 10 10 10 10 10 10 8.57ซึ่งประกอบด้วยอะไร แต่โทรมากขึ้นฟังก์ชั่นแลมบ์ดาแต่ละที่จะสร้างสตริงของที่คล้ายกันยาวบนและบนจนในที่สุดy
กลายเป็น 0 อย่างเห็นได้ชัด สิ่งนี้มีความซับซ้อนเช่นเดียวกับวิธี Eschew ด้านล่าง แต่แทนที่จะอาศัยตรรกะของการควบคุมแบบ if and and or หรือเพียงแค่การรวมสายใหญ่ ๆ เข้าด้วยกัน (และผลสุทธิก็ยิ่งเพิ่มขึ้น ... อาจเป็นไปได้?)
y
ค่าที่ใหญ่ที่สุดที่ฉันสามารถจัดหาและคำนวณได้โดยไม่ต้องใช้ Python ในการโยนข้อผิดพลาดคือ 2 ซึ่งเพียงพอแล้วที่จะลดอินพุตของ max-float ให้กลับมาเป็น 1
สตริงของความยาว 7.625.597.484.987 OverflowError: cannot fit 'long' into an index-sized integer
เป็นเพียงขนาดใหญ่เกินไป:
ฉันควรหยุด
Eschew Math.log
: ไปที่รูต (10--) รูท (ของปัญหา), คะแนน: ฟังก์ชั่นแยกไม่ออกอย่างมีประสิทธิภาพจาก y = 1
การนำเข้าไลบรารีคณิตศาสตร์กำลัง จำกัด จำนวนไบต์ ลองทำอย่างนั้นและแทนที่log(x)
ฟังก์ชั่นด้วยสิ่งที่เทียบเท่ากันx**.1
โดยประมาณ: และมีค่าใช้จ่ายประมาณจำนวนอักขระที่เท่ากัน แต่ไม่จำเป็นต้องนำเข้า ทั้งสองฟังก์ชั่นมีเอาต์พุตแบบไม่เชิงเส้นที่เกี่ยวข้องกับอินพุต แต่ x 0.1จะเติบโตช้ากว่า อย่างไรก็ตามเราไม่ได้สนใจอะไรมากนักเราเพียงแคร์ว่ามันมีรูปแบบการเติบโตพื้นฐานที่เกี่ยวกับตัวเลขจำนวนมากในขณะที่ใช้อักขระที่มีจำนวนใกล้เคียงกัน (เช่น. x**.9
คือจำนวนอักขระเดียวกัน แต่เติบโตเร็วกว่าดังนั้นจึงมี คือค่าที่จะแสดงการเติบโตที่แน่นอนเหมือนกัน)
ตอนนี้จะทำอย่างไรกับ 16 ตัวอักษร แล้ว ... การขยายฟังก์ชั่นแลมบ์ดาของเราให้มีคุณสมบัติของ Ackermann Sequence? คำตอบสำหรับคนจำนวนมากเป็นแรงบันดาลใจให้กับโซลูชันนี้
a=lambda x,y,z:(z<0)*x or y and a(x**.1,z**z,z-1)or a(x**.1,y-1,z)
print a(input(),9,9**9**9**99)//1
z**z
ส่วนที่นี่จะช่วยป้องกันผมจากการทำงานของฟังก์ชั่นนี้กับทุกที่ใกล้ปัจจัยการผลิตสำหรับสติy
และz
ค่านิยมที่ใหญ่ที่สุดที่ผมใช้งานสามารถ 9 และ3ซึ่งผมได้รับกลับค่าของ 1.0 แม้สำหรับที่ใหญ่ที่สุดสนับสนุนลอยหลาม (หมายเหตุ: ในขณะที่ 1.0 6.77538853089e-05 มากกว่าตัวเลขเชิงตัวเลขระดับการเรียกซ้ำที่เพิ่มขึ้นจะย้ายเอาท์พุทของฟังก์ชั่นนี้เข้าใกล้ 1 ในขณะที่เหลือมากกว่า 1 ในขณะที่ฟังก์ชั่นก่อนหน้านี้ย้ายค่าที่ใกล้เคียงกับ 0 ในขณะที่เหลือมากกว่า 0 ส่งผลให้การดำเนินงานจำนวนมากที่จำนวนจุดลอยตัวสูญเสียบิตที่สำคัญทั้งหมด )
การกำหนดค่าการเรียกแลมบ์ดาเดิมให้มีค่าการเรียกซ้ำเป็น 0 และ 2 ...
>>>1.7976931348623157e+308
1.0000000071
หากเปรียบเทียบที่จะทำเพื่อ "ชดเชยจาก 0" แทน "ชดเชยจาก 1" ผลตอบแทนที่ฟังก์ชั่นนี้ซึ่งแน่นอนมีขนาดเล็กกว่า7.1e-9
6.7e-05
การเรียกซ้ำพื้นฐานของโปรแกรมจริง(ค่า z) คือ 10 10 10 10 1.97ระดับลึกทันทีที่ y หมดตัวมันจะได้รับการรีเซ็ตด้วย 10 10 10 10 10 1.97 (ซึ่งเป็นสาเหตุที่ค่าเริ่มต้นที่ 9 เพียงพอ) ดังนั้นฉันจึงไม่ ยังไม่รู้วิธีคำนวณจำนวนการเรียกซ้ำทั้งหมดที่เกิดขึ้นอย่างถูกต้องอีกครั้ง: ฉันมีความรู้ทางคณิตศาสตร์จนจบ ในทำนองเดียวกันฉันไม่ทราบว่าการย้ายหนึ่งในการ**n
ยกกำลังจากอินพุตเริ่มต้นไปยังรองz**z
จะปรับปรุงจำนวนการเรียกซ้ำหรือไม่ (เหมือนกันย้อนกลับ)
ให้ช้าลงด้วยการเรียกซ้ำอีกครั้ง
import math
a=lambda x,y:(y<0)*x or a(a(a(math.log(x+1),y-1),y-1),y-1)
print a(input(),9**9**9e9)//1
n//1
- ประหยัดกว่า 2 ไบต์ int(n)
import math
, math.
ช่วยประหยัด 1 ไบต์มากกว่าfrom math import*
a(...)
บันทึกทั้งหมด 8 ไบต์ m(m,...)
(y>0)*x
บันทึกไบต์มากกว่าy>0and x
9**9**99
เพิ่มจำนวนไบต์ทีละ 4 และเพิ่มความลึกแบบเรียกซ้ำโดยประมาณโดย2.8 * 10^x
ที่x
ความลึกเดิม (หรือความลึกใกล้กับขนาด googolplex: 10 10 94 )
9**9**9e9
เพิ่มจำนวนไบต์ทีละ 5 และเพิ่มความลึกของการเรียกซ้ำโดย ... จำนวนบ้า ลึก recursion คือตอนนี้ 10 10 10 9.93สำหรับการอ้างอิงเป็นกูกอลเพลกซ์คือ 10 10 10 2
- การประกาศแลมบ์ดาทำให้การเรียกซ้ำเพิ่มขึ้นโดยขั้นตอนพิเศษ:
m(m(...))
เป็นa(a(a(...)))
ต้นทุน 7 ไบต์
ใหม่มูลค่าส่งออก (ที่ความลึก 9 ซ้ำ):
>>>1.7976931348623157e+308
6.77538853089e-05
การเรียกซ้ำลึกลงไปถึงจุดที่ผลลัพธ์นี้ไม่มีความหมายอย่างแท้จริงยกเว้นเมื่อเปรียบเทียบกับผลลัพธ์ก่อนหน้าโดยใช้ค่าอินพุตเดียวกัน:
- ต้นฉบับเรียกว่า
log
25 ครั้ง
- การปรับปรุงครั้งแรกเรียกว่า 81 ครั้ง
- จริงโปรแกรมจะเรียกมันว่า 1e99 2หรือประมาณ 10 10 2.3ครั้ง
- รุ่นนี้เรียกมันว่า 729 ครั้ง
- จริงโปรแกรมจะเรียกมันว่า (9 9 99 ) 3หรือน้อยกว่า 10 10 95ครั้ง)
การลงทะเบียนเรียน Lambda คะแนน: ???
ฉันได้ยินคุณชอบ lambdas ดังนั้น ...
from math import*
a=lambda m,x,y:y<0and x or m(m,m(m,log(x+1),y-1),y-1)
print int(a(a,input(),1e99))
ฉันไม่สามารถเรียกใช้สิ่งนี้ได้ฉันสแต็คโอเวอร์โฟลว์แม้มีการเรียกซ้ำเพียง99เลเยอร์
วิธีการเก่า (ด้านล่าง) ผลตอบแทน (ข้ามการแปลงเป็นจำนวนเต็ม):
>>>1.7976931348623157e+308
0.0909072713593
วิธีการใหม่จะส่งกลับโดยใช้การบุกรุกเพียง 9 ชั้น (แทนที่จะเป็นgoogolเต็มรูปแบบของพวกเขา):
>>>1.7976931348623157e+308
0.00196323936205
ฉันคิดว่าวิธีนี้มีความซับซ้อนคล้ายกับลำดับ Ackerman เพียงเล็กน้อยแทนที่จะใหญ่
ขอบคุณ ETHproductions สำหรับการประหยัดแบบ 3 ไบต์ในช่องว่างที่ฉันไม่ทราบว่าสามารถลบออกได้
คำตอบเก่า:
การตัดจำนวนเต็มของบันทึกฟังก์ชั่น (i + 1) ทำซ้ำ20 25 ครั้ง (Python) โดยใช้ lambda'd lambdas
คำตอบของ PyRulez สามารถบีบอัดได้โดยการแนะนำแลมบ์ดาที่สองและซ้อนมัน:
from math import *
x=lambda i:log(i+1)
y=lambda i:x(x(x(x(x(i)))))
print int(y(y(y(y(y(input()))))))
ใช้ 99 100 ตัวอักษร
นี้ผลิตซ้ำของ20 25 กว่าเดิม 12. นอกจากมันจะช่วยประหยัด 2 ตัวอักษรโดยใช้int()
แทนfloor()
ซึ่งได้รับอนุญาตเพื่อเพิ่มx()
สแต็ค หากช่องว่างหลังจากแลมบ์ดาสามารถลบออกได้ (ฉันไม่สามารถตรวจสอบได้ในขณะนี้) y()
สามารถเพิ่มช่องว่างที่ 5 ได้ ! ที่เป็นไปได้
หากมีวิธีการข้ามfrom math
การนำเข้าโดยใช้ชื่อที่ผ่านการรับรอง (เช่น. x=lambda i: math.log(i+1))
) นั่นจะช่วยประหยัดอักขระได้มากขึ้นและอนุญาตให้ใช้สแต็กอื่นx()
แต่ฉันไม่รู้ว่า Python สนับสนุนสิ่งเหล่านี้หรือไม่ (ฉันสงสัยว่าไม่ได้) ทำ!
นี่เป็นกลอุบายแบบเดียวกับที่ใช้ในการโพสต์บล็อกของ XCKD เป็นจำนวนมากอย่างไรก็ตามค่าใช้จ่ายในการประกาศ lambdas จะแยกออกจากสแต็กที่สาม:
from math import *
x=lambda i:log(i+1)
y=lambda i:x(x(x(i)))
z=lambda i:y(y(y(i)))
print int(z(z(z(input()))))
นี่เป็นการเรียกซ้ำที่เล็กที่สุดที่เป็นไปได้ด้วย 3 lambdas ที่เกินความสูงของสแต็กที่คำนวณเป็น 2 lambdas (การลด lambda ใด ๆ ไปยังสองการโทรจะทำให้ความสูงของสแต็คลดลงเหลือ 18 ซึ่งต่ำกว่ารุ่น 2 แลมบ์ดา