Program terminating terpendek yang ukuran outputnya melebihi angka Graham

37

Tulis program sesingkat mungkin (panjang diukur dalam bytes) memenuhi persyaratan berikut:

  • tidak ada input
  • output ke stdout
  • eksekusi akhirnya berakhir
  • jumlah total byte keluaran melebihi jumlah Graham

Asumsikan bahwa program berjalan sampai penghentian "normal" pada komputer ideal 1 dapat mengakses sumber daya tak terbatas, dan bahwa bahasa pemrograman umum dimodifikasi jika perlu (tanpa mengubah sintaks) untuk memungkinkan ini. Karena asumsi-asumsi ini, kita dapat menyebutnya semacam eksperimen Gedanken.

Untuk memulai, berikut adalah program Ruby 73-byte yang menghitung f ω + 1 (99) dalam hierarki yang berkembang cepat :

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: Lebih tepatnya, misalkan kita mengambil sistem yang ada dan memodifikasinya hanya untuk tidak memiliki batas atas pada ukuran penyimpanan (tetapi selalu terbatas). Waktu pelaksanaan instruksi tidak seharusnya dimodifikasi, tetapi mesin dianggap ideal karena tidak akan memiliki batas atas pada masa operasinya.

res
sumber
Ini membawa pertanyaan tetrasi saya ke tingkat yang sama sekali baru!
MrZander
1
Pernah ada kontes pemrograman serupa yang disebut Bignum Bakeoff. Beberapa entri cukup menarik; hasilnya ada di sini: djm.cc/bignum-results.txt
Danny Chia

Jawaban:

11

GolfScript ( 49 47 karakter)

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

Lihat Lifetime of a worm untuk banyak penjelasan. Singkatnya, ini mencetak angka yang lebih besar dari f ω ω (2).

Peter Taylor
sumber
f_ (ω ^ ω) (2) kira-kira sebesar g_ (f_8 (8)), jadi tidak berlebihan seperti ungkapan yang akan diimplikasikan.
Simply Beautiful Art
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

Cara kerjanya: %cukup ambil fungsi dan buat n-1waktu di atas s; yaitu %3mengambil fungsi fdan mengembalikan fungsi nyang sama dengan menerapkannya fke 3, n-1kali berturut-turut. Jika kita mengulangi penerapan fungsi tingkat tinggi ini, kita mendapatkan urutan fungsi yang tumbuh cepat - dimulai dengan eksponensial, itu persis urutan ukuran hutan panah Knuth:
((%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
dan seterusnya. ((%3)%(3^))n 3adalah 3 ↑ⁿ 3, yang adalah apa yang muncul dalam perhitungan ke nomor Graham. Yang tersisa untuk dilakukan adalah menyusun fungsi(\n -> 3 ↑ⁿ 3) ≡ flip((%3)%(3^))3lebih dari 64 kali, di atas 4 (jumlah panah yang dimulai dengan perhitungan), untuk mendapatkan angka yang lebih besar dari angka Graham. Jelas bahwa logaritma (fungsi yang sangat lambat!) g₆₅Masih lebih besar daripada g₆₄=G, jadi jika kita mencetak angka itu, panjang outputnya melebihi G.

berhenti mengubah counterclockwis
sumber
Ketika saya menguji ini dengan print$((flip((%3)%(3*))3)%2)1, ada kesalahan run-time - dapatkah Anda mengatakan mengapa? Ini berhasil ketika 2diubah ke 1(output adalah 81).
res
Oh ... ideone tampaknya menjalankan versi 32-bit, sehingga meluap Intdengan cepat. Pada sistem 64-bit, yang menghabiskan terlalu banyak memori untuk direproduksi, tetapi tentu saja masih tidak memungkinkan untuk dijangkau G. Saya membutuhkan tipe (big-int) Integer, jadi saya tidak bisa menggunakan !!; tunggu ...
berhenti mengaktifkan counterclockwis
Memperbaikinya sekarang, harus menggunakan rekursi eksplisit untuk menerapkan %.
Berhenti menghidupkan counterclockwis
Saya menemukan ((%3)%(3*))2 nsebenarnya tumbuh lebih cepat dari yang Anda katakan ( hal yang baik ), tetapi Haskell-fu saya tidak cukup untuk memahami mengapa. Karena n = 0, 1, 2, ..., alih-alih memberi 3, 3^3, 3^(3^3), ..., ia memberi 3, 3^(3+1), 3^((3^(3+1))+1), ....
res
Seperti yang saya katakan: " ((%3)%(3*))n 3adalah lebih besar daripada 3 ↑ⁿ 3". Atau maksud Anda sesuatu yang lain? Ngomong-ngomong, saya mengubah definisi sehingga semuanya setara (setidaknya saya kira begitu, untuk malas memeriksanya sekarang ...) daripada lebih besar. Dan jika Anda mengubah 66ke 65, itu benar-benar menghasilkan Gsendiri, bukankah itu bagus?
Berhenti menghidupkan counterclockwis
5

Pyth , 29 28 byte

M?*GHgtGtgGtH^ThH=ZTV99=gZTZ

Menentukan lambda untuk hiper-operasi dan menyebutnya secara berulang. Seperti definisi untuk nomor Graham, tetapi dengan nilai yang lebih besar.

Ini:

M?*GHgtGtgGtH^3hH

Mendefinisikan lambda, kira-kira sama dengan python

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

Ini memberikan fungsi hiper-operasi, g (G, H) = 3 ↑ G + 1 (H + 1).
Jadi, misalnya, g (1,2) = 3 ↑ 2 3 = 7.625.597.484.987, yang dapat Anda uji di sini .

V<x><y>mulai loop yang mengeksekusi tubuh y,, xkali.
=gZTadalah badan loop di sini, yang setara denganZ=g(Z,10)

Kode:

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

Harus secara berulang memanggil hiperoperasi di atas 64 kali, memberikan Nomor Graham.

Namun, dalam jawaban saya, saya telah mengganti satu digit T, yang diinisialisasi ke 10, dan meningkatkan kedalaman rekursi menjadi 99. Menggunakan Notasi Graham Array , Nomor Graham adalah [3,3,4,64], dan nomor saya output program yang lebih besar [10,11,11,99]. Saya juga menghapus )yang menutup loop untuk menyimpan satu byte, sehingga mencetak setiap nilai berturut-turut dalam 99 iterasi.

KSmarts
sumber
3

Python (111 + n), n = panjang (x)

Meskipun yang ini tidak sesingkat program Ruby penjawab, saya tetap akan mempostingnya, untuk mengesampingkan kemungkinan ini.

Ini menggunakan fungsi Ackermann, dan memanggil fungsi Ackermann dengan m dan n menjadi nilai dari panggilan lain ke fungsi Ackermann, dan berulang 1000 kali.

Ini mungkin lebih besar dari jumlah Graham, tetapi saya tidak yakin, karena tidak ada yang tahu persis panjangnya. Ini dapat dengan mudah diperpanjang, jika tidak lebih besar.

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))
beary605
sumber
output ke stdout? juga, Anda memerlukan returnpernyataan atau lambda.
Stanby
7
Juga jika A (m, n) mengembalikan nilai tunggal, maka bukankah A (A (5,5)) melewatkan argumen? ... Ini adalah masalah dengan tantangan seperti ini: ini mendorong orang untuk tidak menguji kode mereka, karena menjalankan sepenuhnya adalah murni teoretis.
kotak roti
Jika Anda mengganti baris terakhir dengan exec'x=A(x,x);'*x;print x, maka programnya ok dan outputnya kira-kira f_ (ω + 1) (x) (anggap kode fungsi Ackermann sudah benar), yang memiliki lebih dari G byte bahkan untuk x = 99, katakan . (Dalam program Ruby saya, f[m,n]adalah versi A(m,n).)
res
@breadbox - Poin bagus ... Pertanyaan teoretis seperti ini mengharuskan kami untuk memastikan program tidak masalah untuk parameter uji kecil (yaitu non-teoritis) yang secara umum menggeneralisasi untuk memberikan jawaban yang benar.
res
1
Ini lebih panjang, tetapi jika Anda ingin menggunakannya evalsebagai ganti exec, baris terakhir Anda bisa saja f=lambda x:A(x,x);print eval('f('*x+'x'+')'*x). Selain itu, definisi A (m, n) Anda perlu dikoreksi per komentar stan.
res
2

Ruby, 54 52 50 byte

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 byte

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

Hirarki yang tumbuh sangat cepat dengan f (a + 1)> f ω + 1 (a).


Ruby, 61 byte

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]

Pada dasarnya fungsi Ackermann dengan twist.


Ruby, 63 59 byte

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

Ruby lain, 74 71 byte

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

Pada dasarnya Ackermann berfungsi untuk dirinya sendiri 99 kali.

Seni Cukup Indah
sumber
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

Yang mungkin bisa dipersingkat menjadi 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)

Di mana Xangka besar yang sesuai sehingga hiperoperasi yang dihasilkan 3, 3lebih besar dari angka Grahams (jika angka ini kurang dari 99999999999beberapa byte disimpan).


Catatan: Saya menganggap kode python dieksekusi pada interpreter interaktif sehingga hasilnya dicetak ke stdout, jika tidak tambahkan 9byte ke setiap solusi untuk panggilan ke print.

Bakuriu
sumber
2
Solusi 74ish byte Anda tidak menghasilkan output yang hampir cukup besar.
lirtosiast
0

Javascript, 83 byte

Solusi fungsi Ackermann lainnya.

(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)
SuperJedi224
sumber
0

JavaScript, 68 byte, namun tidak bersaing untuk menggunakan 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 fungsinya mirip dengan notasi panah atas dengan basis 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

bfungsi adalah: b (x) = b x (9).

b(99)adalah ~ f ω +1 (99), dibandingkan dengan nomor Graham <f ω + 1 (64).

Naruyoko
sumber
Jika Anda menandai ini tidak bersaing karena bahasa lebih baru daripada pertanyaan, Anda tidak perlu melakukan itu lagi
Jo King