โปรแกรมยกเลิกที่สั้นที่สุดที่ขนาดเอาต์พุตเกินจำนวนของ Graham


37

เขียนโปรแกรมที่สั้นที่สุดที่เป็นไปได้ (ความยาวที่วัดได้เป็นไบต์) ตรงตามข้อกำหนดต่อไปนี้:

  • ไม่มีการป้อนข้อมูล
  • เอาต์พุตคือ stdout
  • การดำเนินการสิ้นสุดลงในที่สุด
  • จำนวนเอาต์พุตรวมทั้งหมดเกินจำนวนของ Graham

สมมติว่าโปรแกรมทำงานจนกว่าจะสิ้นสุด "ปกติ" บนคอมพิวเตอร์ในอุดมคติ1สามารถเข้าถึงทรัพยากรได้ไม่ จำกัด และภาษาโปรแกรมทั่วไปจะถูกแก้ไขหากจำเป็น (โดยไม่ต้องเปลี่ยนไวยากรณ์) เพื่ออนุญาตสิ่งนี้ เนื่องจากสมมติฐานเหล่านี้เราอาจเรียกสิ่งนี้ว่า Gedankenexperiment

เพื่อเริ่มต้นสิ่งต่าง ๆ นี่คือโปรแกรม Ruby ขนาด 73 ไบต์ที่คำนวณ f ω + 1 (99) ในลำดับชั้นที่เติบโตอย่างรวดเร็ว :

f=proc{|k,n|k>0?n.times{n=f[k-1,n]}:n+=1;n};n=99;n.times{n=f[n,n]};puts n

1 EDIT: แม่นยำยิ่งขึ้นสมมติว่าเรากำลังใช้ระบบที่มีอยู่และปรับเปลี่ยนเพื่อให้ไม่มีขีด จำกัด สูงสุดของขนาดพื้นที่เก็บข้อมูล (แต่มันก็ จำกัด เสมอ) คำสั่งในการประมวลผลของเวลานั้นไม่ควรจะถูกแก้ไข แต่เครื่องจะถือว่าเหมาะสมที่สุดว่าจะไม่มีขีด จำกัด สูงสุดในช่วงอายุการใช้งาน


นี้จะใช้เวลาของฉันtetrationคำถามไปยังระดับใหม่ทั้งหมด!
MrZander

1
ครั้งหนึ่งเคยมีการแข่งขันเขียนโปรแกรมคล้ายกันเรียกว่า Bignum Bakeoff บางส่วนของรายการที่น่าสนใจมาก ผลลัพธ์อยู่ที่นี่: djm.cc/bignum-results.txt
Danny Chia

คำตอบ:


11

GolfScript ( 49 47 ตัวอักษร)

4.,{\):i\.0={.0+.({<}+??\((\+.@<i*\+}{(;}if.}do

ดูคำอธิบายของอายุการใช้งานของหนอน ในระยะสั้นนี้พิมพ์มากกว่าจำนวนกว่าฉโอห์มโอห์ม (2)


f_ (ω ^ ω) (2) มีขนาดใหญ่พอ ๆ กับ g_ (f_8 (8)) ดังนั้นจึงไม่เกินความสามารถของนิพจน์ดังกล่าว
ศิลปะที่สวยงามเพียง

21

Haskell, 59 57 55 63

(f%s)1=s;(f%s)n=f.(f%s)$n-1
main=print$((flip((%3)%(3^))3)%4)66

มันทำงานอย่างไร: %ใช้ฟังก์ชั่นและเรียบเรียงมันเป็นn-1เวลาs; คือ%3รับฟังก์ชั่นfและส่งกลับฟังก์ชั่นของnที่เท่ากับใช้fกับ 3 n-1ครั้งในแถว ถ้าเราย้ำประยุกต์ใช้ฟังก์ชั่นขั้นสูงนี้เราได้รับลำดับที่เติบโตอย่างรวดเร็วของการทำงาน - เริ่มต้นด้วยการยกกำลังก็ว่าลำดับของขนาดนูลูกศร-ป่า:
((%3)%(3^))1 n = (3^)n     = 3ⁿ = 3↑n
((%3)%(3^))2 n = ((3^)%3)n = (3↑)ⁿ⁻¹ $ 3 = 3↑↑n
((%3)%(3^))3 n = (((3^)%3)%3)n = (3↑↑)ⁿ⁻¹ $ 3  = 3↑↑↑n
และอื่น ๆ ((%3)%(3^))n 3คือ3 ↑ⁿ 3สิ่งที่ปรากฏในการคำนวณตามจำนวนของ Graham สิ่งที่เหลือให้ทำคือการเขียนฟังก์ชั่น(\n -> 3 ↑ⁿ 3) ≡ flip((%3)%(3^))3มากกว่า 64 ครั้งที่ด้านบนของ 4 (จำนวนลูกศรที่การคำนวณเริ่มต้นด้วย) เพื่อให้ได้ตัวเลขที่มากกว่าเลขของเกรแฮม มันเห็นได้ชัดว่าลอการิทึม (สิ่งที่ฟังก์ชั่นช้ากะเผลกที่เป็น!) ของg₆₅ยังคงมีขนาดใหญ่กว่าดังนั้นหากเราพิมพ์ตัวเลขที่ระยะเวลาในการส่งออกสูงกว่าg₆₄=GG


เมื่อฉันทดสอบสิ่งนี้ด้วยprint$((flip((%3)%(3*))3)%2)1มีข้อผิดพลาดรันไทม์ - คุณพูดได้ไหมว่าทำไม มันจะประสบความสำเร็จเมื่อ2เปลี่ยนเป็น1(ผลผลิตคือ 81)
res

โอ้ ... ideone ดูเหมือนจะใช้เวอร์ชั่น 32 บิตดังนั้นมันจึงเกินความIntรวดเร็ว บนระบบ 64 บิตที่กินหน่วยความจำมากเกินไปที่จะทำซ้ำ Gแต่แน่นอนก็ยังจะไม่อนุญาตให้มีการเข้าถึง ฉันต้องการ (ใหญ่ int) Integerชนิดดังนั้นผมจึงไม่สามารถใช้!!; เดี๋ยวก่อน ...
หยุดหันมาแย่งล็อคกัน

%คงที่ได้ในขณะนี้มีการใช้การเรียกซ้ำอย่างชัดเจนในการดำเนินการ
หยุดหมุนทวนเข็มนาฬิกาเมื่อ

ฉันคิดว่า((%3)%(3*))2 nจริง ๆ แล้วเติบโตเร็วกว่าที่คุณพูด ( สิ่งดี ) แต่ Haskell-fu ของฉันไม่เพียงพอที่จะเข้าใจว่าทำไม สำหรับn = 0, 1, 2, ...แทนการให้จะช่วยให้3, 3^3, 3^(3^3), ... 3, 3^(3+1), 3^((3^(3+1))+1), ...
res

ขณะที่ผมกล่าวว่า " ((%3)%(3*))n 3เป็นขนาดใหญ่กว่า3 ↑ⁿ 3" หรือคุณหมายถึงอย่างอื่น? อย่างไรก็ตามฉันเปลี่ยนคำจำกัดความเพื่อให้เท่าเทียมกัน (อย่างน้อยฉันก็คิดว่าเป็นคนขี้เกียจที่จะตรวจสอบตอนนี้ ... ) มากกว่าคนที่มีขนาดใหญ่กว่า และถ้าคุณเปลี่ยน66ไป65มันจะสร้างGตัวมันขึ้นมาเอง
หยุดที่จะเปลี่ยนรหัสลับเมื่อ

5

Pyth , 29 28 ไบต์

M?*GHgtGtgGtH^ThH=ZTV99=gZTZ

กำหนดแลมบ์ดาสำหรับการใช้งานแบบไฮเปอร์และเรียกมันซ้ำ ๆ ชอบนิยามของหมายเลขของ Graham แต่มีค่ามากกว่า

นี้:

M?*GHgtGtgGtH^3hH

กำหนดแลมบ์ดาเท่ากับงูเหลือม

g = lambda G, H:
  g(G-1, g(G, H-1)-1) if G*H else 3^(H+1)

ฟังก์ชั่นนี้ทำให้ฟังก์ชั่นไฮเปอร์ - ดำเนินการ, g (G, H) = 3 ↑ G + 1 (H + 1)
ดังนั้นสำหรับตัวอย่างเช่นกรัม (1,2) = 3 ↑ 2 3 = 7,625,597,484,987, ซึ่งคุณสามารถทดสอบที่นี่

V<x><y>เริ่มวนรอบที่เรียกใช้งานร่างกายy,, xครั้ง
=gZTคือเนื้อความของลูปที่นี่ซึ่งเทียบเท่ากับZ=g(Z,10)

รหัส:

M?*GHgtGtgGtH^3hH=Z3V64=gZ2)Z

ควรเรียก hyperoperation ซ้ำมากกว่า 64 ครั้งโดยระบุหมายเลขของ Graham

ในคำตอบของฉัน แต่ฉันได้แทนที่ตัวเลขเดียวด้วยTซึ่งจะเริ่มต้นที่ 10 และเพิ่มความลึกของการเรียกซ้ำเป็น 99 การใช้สัญกรณ์เกรแฮม Array สัญกรณ์หมายเลขเกรแฮมคือ [3,3,4,64] และของฉัน โปรแกรมให้ผลลัพธ์ที่ใหญ่กว่า [10,11,11,99] ฉันได้ลบส่วน)ที่ปิดลูปออกเพื่อบันทึกหนึ่งไบต์ดังนั้นมันจึงพิมพ์ค่าที่ต่อเนื่องกันใน 99 การทำซ้ำ


3

Python (111 + n), n = ความยาว (x)

แม้ว่าอันนี้จะไม่สั้นเท่ากับโปรแกรม Ruby ของผู้ตอบฉันจะโพสต์ต่อไปเพื่อกำจัดความเป็นไปได้นี้

มันใช้ฟังก์ชั่น Ackermann และเรียกใช้ฟังก์ชั่น Ackermann กับ m และ n เป็นค่าจากการเรียกไปยังฟังก์ชั่น Ackermann อีกครั้งและเรียกซ้ำ 1,000 ครั้ง

นี่อาจใหญ่กว่าหมายเลขของ Graham แต่ฉันไม่แน่ใจเพราะไม่มีใครรู้ว่ามันมีความยาวเท่าไหร่ สามารถขยายได้อย่างง่ายดายหากไม่ใหญ่ขึ้น

x=999
b='A('*x+'5,5'+')'*x
def A(m,n):n+1 if m==0 else A(m-1,A(m,n-1)if n>0 else 1)
exec('print A('%s,%s')'%(b,b))

ส่งออกไปยัง stdout? นอกจากนี้ยังมีคุณจำเป็นต้องมีคำสั่งหรือreturn lambda
บูธโดย

7
นอกจากนี้หาก A (m, n) ส่งคืนค่าเดียวดังนั้น A (A (5,5)) จึงไม่มีอาร์กิวเมนต์? ... นี่เป็นปัญหาของการท้าทายเช่นนี้: มันกระตุ้นให้คนไม่ทดสอบรหัสของพวกเขา
breadbox

หากคุณแทนที่บรรทัดสุดท้ายด้วยexec'x=A(x,x);'*x;print xโปรแกรมจะทำงานและผลลัพธ์จะอยู่ที่ประมาณ f_ (ω + 1) (x) (สมมติว่ารหัสฟังก์ชัน Ackermann นั้นถูกต้อง) ซึ่งมีมากกว่า G ไบต์ถึง x = 99 . (ในโปรแกรม Ruby ของฉันf[m,n]เป็นรุ่นA(m,n))
res

@breadbox - จุดดี ... คำถามเชิงทฤษฎีเช่นนี้ต้องการให้เราตรวจสอบให้แน่ใจว่าโปรแกรมนั้นใช้ได้สำหรับกรณีทดสอบขนาดเล็กแบบพารามิเตอร์ (เช่นที่ไม่ใช่เชิงทฤษฎี) ซึ่งเห็นได้อย่างชัดเจนทั่วไปเพื่อให้คำตอบที่ถูกต้อง
res

1
ของมันอีกต่อไป แต่ถ้าคุณต้องการที่จะใช้evalแทนบรรทัดสุดท้ายของคุณอาจจะexec f=lambda x:A(x,x);print eval('f('*x+'x'+')'*x)นอกจากนี้ def ของคุณของ A (m, n) จะต้องได้รับการแก้ไขตามความคิดเห็นของบูธ
res

2

Ruby, 54 52 50 ไบต์

f=->b{a*=a;eval"f[b-1];"*b*a};eval"f[a];"*a=99;p a

Ruby, 85 81 76 71 68 64 63 59 57 ไบต์

f=->a,b=-a{eval"a*=b<0?f[a,a]:b<1?a:f[a,b-1];"*a};p f[99]

ลำดับชั้นที่เติบโตอย่างรวดเร็วมากด้วย f (a + 1)> f ω + 1 (a)


Ruby, 61 ไบต์

f=->a,b=-a{a<0?9:b==0?a*a:f[f[a-1,b],b>0?b-1:f[a,b+1]]};f[99]

โดยทั่วไปฟังก์ชั่น Ackermann กับบิด


ทับทิม, 63 59 ไบต์

n=99;(H=->a{b,*c=a;n.times{b ?H[[b-1]*n*b+c]:n+=n}})[n];p n

รูบี้อีกอัน, 74 71 ไบต์

def f(a,b=a)a<0?b:b<0?f(a-1):f(a-1,f(a,b-1))end;n=99;n.times{n=f n};p n

โดยพื้นฐาน Ackermann ทำงานเพื่อตัวเอง 99 ครั้ง


0

Python: 85

f=lambda a,a:a*a
exec'f=lambda a,b,f=f:reduce(f,[a]*b,1)'*99
exec'f('*64+'3'+',3)'*64

ซึ่งอาจสั้นลงเหลือ74+length(X) :

f=lambda a,a:a*a
exec'f=lambda a,b,f=f:reduce(f,[a]*b,1)'*int('9'*X)
f(3,3)

ที่ไหนXเป็นจำนวนมากที่เหมาะสมเช่น hyperoperation ผลลัพธ์ที่เกิดขึ้น3, 3มีขนาดใหญ่กว่าหมายเลข Grahams (ถ้าจำนวนนี้น้อยกว่า99999999999นั้นบางไบต์จะถูกบันทึก)


หมายเหตุ: ผมถือว่ารหัสหลามที่จะดำเนินการในล่ามโต้ตอบด้วยเหตุนี้ผลที่ได้คือพิมพ์ที่ stdout มิฉะนั้นเพิ่มไบต์ในแต่ละวิธีแก้ปัญหาสำหรับการเรียกร้องให้9print


2
โซลูชัน 74ish ไบต์ของคุณไม่ได้สร้างผลลัพธ์ที่มีขนาดใหญ่พอ
lirtosiast

0

Javascript, 83 ไบต์

อีกฟังก์ชั่นโซลูชั่น Ackermann

(function a(m,n,x){return x?a(a(m,n,x-1),n,0):(m?a(m-1,n?a(m,n-1):1):n+1)})(9,9,99)

0

JavaScript, 68 ไบต์, อย่างไรก็ตามการยกเลิกการใช้ ES6

a=(x,y)=>y?x?a(a(x-1,y)*9,y-1):a(9,y-1):x;b=x=>x?a(9,b(x-1)):9;b(99)

a ฟังก์ชั่นคล้ายกับสัญลักษณ์ลูกศรขึ้นกับฐาน 9

       /a(a(x-1,y)*9,y-1)  x>0, y>0
a(x,y)=|a(9,y-1)           x=0, y>0
       \x                  y=0

bฟังก์ชั่นคือ: b (x) = b x (9)

b(99)คือ ~ f ω + 1 (99) เมื่อเปรียบเทียบกับหมายเลขของ Graham <f ω + 1 (64)


หากคุณทำเครื่องหมายว่าไม่ใช่การแข่งขันเนื่องจากภาษาใหม่กว่าคำถามคุณไม่ต้องทำแบบนั้นอีกต่อไป
Jo King
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.