Самая короткая завершающая программа, выходной размер которой превышает число Грэма


37

Напишите кратчайшую возможную программу (длина измеряется в байтах), удовлетворяющую следующим требованиям:

  • нет ввода
  • вывод на стандартный вывод
  • исполнение в конечном итоге прекращается
  • общее количество выходных байтов превышает число Грэма

Предположим, что программы работают до «нормального» завершения на идеальном компьютере 1, способном получить доступ к неограниченным ресурсам, и что общие языки программирования модифицируются, если необходимо (без изменения синтаксиса), чтобы разрешить это. Из-за этих предположений мы могли бы назвать это своего рода Gedankenexperiment.

Для начала, вот 73-байтовая программа Ruby, которая вычисляет 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 РЕДАКТИРОВАТЬ: Точнее, предположим, что мы берем существующую систему и модифицируем ее только для того, чтобы не было верхнего предела размера хранилища (но он всегда конечен). Время выполнения инструкций не должно изменяться, но предполагается, что машина идеальна в том смысле, что у нее не будет верхнего предела срока ее службы.


Это поднимает мой вопрос о тетратации на совершенно новый уровень!
MrZander

1
Был когда-то подобный конкурс программирования под названием Bignum Bakeoff. Некоторые из записей довольно интересные; результаты здесь: djm.cc/bignum-results.txt
Дэнни Чиа

Ответы:


11

GolfScript ( 49 47 символов)

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

Смотрите Lifetime червя для большого количества объяснений. Короче говоря, это печатает число больше, чем f ω ω (2).


f_(ω^ω)(2) is about as large as g_(f_8(8)), so not as overkill as that expression would imply.
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

How it works: % simply takes a function and composes it n-1 times on top of s; i.e. %3 takes a function f and returns a function of n that equals applying it f to 3, n-1 times in a row. If we iterate the application of this higher-order function, we get a fast-growing sequence of functions – starting with exponentiation, it's exactly the sequence of Knuth-arrow-forest sizes:
((%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
and so on. ((%3)%(3^))n 3 is 3 ↑ⁿ 3, which is what appears in the calculation to Graham's number. All that's left to do is composing the function (\n -> 3 ↑ⁿ 3) ≡ flip((%3)%(3^))3 more than 64 times, on top of 4 (the number of arrows the calculation starts with), to get a number larger than Graham's number. It's obvious that the logarithm (what a lamely slow function that is!) of g₆₅ is still larger than g₆₄=G, so if we print that number the output length exceeds G.


When I test this with print$((flip((%3)%(3*))3)%2)1, there's a run-time error - can you say why? It succeeds when the 2 is changed to 1 (output is 81).
r.e.s.

Oh... ideone seems to run a 32-bit version, so it gets to an overflow of Int quickly. On a 64-bit system, that consumes too much memory to reproduce, but of course it still won't allow to reach G. I need the (big-int) Integer type, so I can't use !!; wait...
ceased to turn counterclockwis

Fixed it now, had to use explicit recursion to implement %.
ceased to turn counterclockwis

I find ((%3)%(3*))2 n actually grows faster than you say (a good thing), but my Haskell-fu is inadequate to understand why. For n = 0, 1, 2, ..., instead of giving 3, 3^3, 3^(3^3), ..., it gives 3, 3^(3+1), 3^((3^(3+1))+1), ....
r.e.s.

As I said: "((%3)%(3*))n 3 is larger than 3 ↑ⁿ 3". Or do you mean something else? Anyway, I changed the definition so that it's all equalities (at least I think so, to lazy to check now...) rather than larger-thans. And if you change 66 to 65, it actually produces G itself, ain't that nice?
ceased to turn counterclockwis

5

Pyth, 29 28 bytes

M?*GHgtGtgGtH^ThH=ZTV99=gZTZ

Defines a lambda for hyper-operation and recursively calls it. Like the definition for Graham's number, but with larger values.

This:

M?*GHgtGtgGtH^3hH

Defines a lambda, roughly equal to the python

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

This gives the hyper-operation function, g(G,H) = 3↑G+1(H+1).
So, for example, g(1,2)=3↑23 = 7,625,597,484,987, which you can test here.

V<x><y> starts a loop that executes the body, y, x times.
=gZT is the body of the loop here, which is equivalent to Z=g(Z,10)

The code:

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

Should recursively call the hyperoperation above 64 times, giving Graham's Number.

In my answer, however, I've replaced the single digits with T, which is initialized to 10, and increased the depth of recursion to 99. Using Graham Array Notation, Graham's Number is [3,3,4,64], and my program outputs the larger [10,11,11,99]. I've also removed the ) that closes the loop to save one byte, so it prints each successive value in the 99 iterations.


3

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

Although this one is not as short as the answerer's Ruby program, I'll post it anyway, to rule this possibility out.

It uses the Ackermann function, and calls the Ackermann function with m and n being the values from another call to the Ackermann function, and recurses 1000 times.

This is probably bigger than Graham's number, but I'm not sure, because nobody knows the exact length of it. It can be easily extended, if it's not bigger.

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))

output to stdout? also, you need a return statement or a lambda.
boothby

7
Also if A(m,n) returns a single value, then isn't A(A(5,5)) missing an argument? ... This is the problem with a challenge like this: it encourages people not to test their code, because a complete run is purely theoretical.
breadbox

If you replace your last line with exec'x=A(x,x);'*x;print x, then the program is ok and the output is approximately f_(ω+1)(x) (assumimg the Ackermann function code is correct), which has more than G bytes even for x=99, say. (In my Ruby program, f[m,n] is a version of A(m,n).)
r.e.s.

@breadbox - Good point ... Theoretical questions like this require us to make sure a program is ok for small-parameter (i.e. non-theoretical) test-cases that clearly generalize to give a correct answer.
r.e.s.

1
Its's longer, but if you want to use eval instead of exec, your last line could be f=lambda x:A(x,x);print eval('f('*x+'x'+')'*x). Also, your def of A(m,n) needs to be corrected per boothby's comment.
r.e.s.

2

Ruby, 54 52 50 bytes

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 bytes

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

Pretty much fast growing hierarchy with f(a+1) > fω+1(a).


Ruby, 61 bytes

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]

Basically an Ackermann function with a twist.


Ruby, 63 59 bytes

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

Another Ruby, 74 71 bytes

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

Basically Ackermann function to itself 99 times.


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

Which maybe could be shortened to 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)

Where X is an appropriate big number such that the resultant hyperoperation on 3, 3 is bigger than Grahams number(if this number is less than 99999999999 then some byte is saved).


Note: I assume the python code is executed on the interactive interpreter hence the result is printed to stdout, otherwise add 9 bytes to each solution for the call to print.


2
Your 74ish byte solution does not produce an output nearly large enough.
lirtosiast

0

Javascript, 83 bytes

Another Ackermann function solution.

(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 bytes, however uncompeting for using 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 function is similar to up-arrow notation with base 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 function is: b(x)=bx(9).

b(99) is ~fω+1(99), compared to Graham's number<fω+1(64).


If you've marked this non-competing due to the language being newer than the question, you don't have to do that anymore
Jo King
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.