Programa de terminação mais curto, cujo tamanho de saída excede o número de Graham


37

Escreva o programa mais curto possível (comprimento medido em bytes) atendendo aos seguintes requisitos:

  • sem entrada
  • saída é stdout
  • a execução termina eventualmente
  • o número total de bytes de saída excede o número de Graham

Suponha que os programas sejam executados até a finalização "normal" em um computador ideal 1 capaz de acessar recursos ilimitados e que as linguagens de programação comuns sejam modificadas, se necessário (sem alterar a sintaxe) para permitir isso. Devido a essas suposições, podemos chamar isso de uma espécie de experiência Gedanken.

Para começar, aqui está um programa Ruby de 73 bytes que calcula f ω + 1 (99) na hierarquia de rápido crescimento :

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: Mais precisamente, suponha que estamos pegando um sistema existente e modificando-o apenas para não ter limite superior no tamanho do armazenamento (mas é sempre finito). Os tempos de execução das instruções não devem ser modificados, mas presume-se que a máquina seja ideal, pois não terá limite superior na vida útil de operação.


Isso leva minha pergunta de tetragem a um nível totalmente novo!
MrZander

11
Houve um concurso de programação semelhante chamado Bignum Bakeoff. Algumas das entradas são bastante interessantes; os resultados estão aqui: djm.cc/bignum-results.txt
Danny Chia

Respostas:


11

GolfScript ( 49 47 caracteres)

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

Veja a vida de um verme para muitas explicações. Em resumo, isso imprime um número maior que f ω ω (2).


f_ (ω ^ ω) (2) é quase tão grande quanto g_ (f_8 (8)), portanto não é um exagero como a expressão implicaria.
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

Como funciona: %simplesmente pega uma função e a compõe várias n-1vezes s; isto é, %3pega uma função fe retorna uma função nigual a aplicá-la fa 3, n-1vezes seguidas. Se iterarmos a aplicação dessa função de ordem superior, obteremos uma sequência de funções que cresce rapidamente - começando pela exponenciação, é exatamente a sequência dos tamanhos de floresta de flechas de 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
e assim por diante. ((%3)%(3^))n 3é 3 ↑ⁿ 3, que é o que aparece no cálculo do número de Graham. Tudo o que resta a fazer é compor a função(\n -> 3 ↑ⁿ 3) ≡ flip((%3)%(3^))3mais de 64 vezes, além de 4 (o número de setas com o qual o cálculo começa), para obter um número maior que o número de Graham. É óbvio que o logaritmo (que função é muito lenta!) De g₆₅ainda é maior que g₆₄=G, portanto, se imprimirmos esse número, o comprimento da saída excederá G.


Quando eu testar isso com print$((flip((%3)%(3*))3)%2)1, há um erro de tempo de execução - você pode dizer por quê? É bem-sucedido quando o 2é alterado para 1(a saída é 81).
res

Oh ... o ideone parece executar uma versão de 32 bits, então chega a um estouro Intrapidamente. Em um sistema de 64 bits, isso consome muita memória para reproduzir, mas é claro que ainda não permitirá alcançar G. Eu preciso do tipo (big-int) Integer, então não posso usar !!; aguarde ...
deixou de girar contra-

Corrigido agora, tinha que usar recursão explícita para implementar %.
deixou de girar contra-relógiowis

Acho que ((%3)%(3*))2 nna verdade cresce mais rápido do que você diz (uma coisa boa ), mas meu Haskell-fu é inadequado para entender o porquê. Pois n = 0, 1, 2, ..., em vez de dar 3, 3^3, 3^(3^3), ..., dá 3, 3^(3+1), 3^((3^(3+1))+1), ....
res

Como eu disse: " ((%3)%(3*))n 3é maior que 3 ↑ⁿ 3". Ou você quer dizer outra coisa? De qualquer forma, mudei a definição para que todas as igualdades (pelo menos eu acho que seja, com preguiça de verificar agora ...) em vez de maiores que. E se você mudar 66para 65, ele realmente se produz G, não é legal?
deixou de girar contra-relógiowis

5

Pitão , 29 28 bytes

M?*GHgtGtgGtH^ThH=ZTV99=gZTZ

Define um lambda para hiperoperação e o chama recursivamente. Como a definição para o número de Graham, mas com valores maiores.

Este:

M?*GHgtGtgGtH^3hH

Define um lambda, aproximadamente igual ao python

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

Isso fornece a função de hiperoperação, g (G, H) = 3 ↑ G + 1 (H + 1).
Então, por exemplo, g (1,2) = 3 ↑ 2 3 = 7.625.597.484.987, que você pode testar aqui .

V<x><y>inicia um ciclo que executa o corpo, y, xvezes.
=gZTé o corpo do loop aqui, que é equivalente aZ=g(Z,10)

O código:

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

Deve recursivamente chamar a hiperoperação acima de 64 vezes, fornecendo o Número de Graham.

Na minha resposta, no entanto, substituí os dígitos únicos com T, inicializados em 10, e aumentei a profundidade da recursão para 99. Usando a Notação Graham Array , o Número de Graham é [3,3,4,64] e meu o programa gera o maior [10,11,11,99]. Também removi o )que fecha o loop para salvar um byte, para que ele imprima cada valor sucessivo nas 99 iterações.


3

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

Embora este não seja tão curto quanto o programa Ruby do respondente, eu o publicarei de qualquer maneira, para descartar essa possibilidade.

Ele usa a função Ackermann e chama a função Ackermann com m e n sendo os valores de outra chamada para a função Ackermann, e se repete 1000 vezes.

Provavelmente é maior que o número de Graham, mas não tenho certeza, porque ninguém sabe o tamanho exato. Pode ser facilmente estendido, se não for maior.

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

saída para stdout? Além disso, você precisa de uma returndeclaração ou a lambda.
Boothby

7
Além disso, se A (m, n) retorna um único valor, então A (A (5,5)) não está perdendo um argumento? ... Esse é o problema de um desafio como este: ele encoraja as pessoas a não testar seu código, porque uma execução completa é puramente teórica.
breadbox

Se você substituir sua última linha por exec'x=A(x,x);'*x;print x, o programa está ok e a saída é aproximadamente f_ (ω + 1) (x) (assumindo que o código de função de Ackermann esteja correto), que possui mais de G bytes, mesmo para x = 99, digamos . (No meu programa Ruby, f[m,n]é uma versão do A(m,n).)
res

@breadbox - Bom argumento ... Questões teóricas como essa exigem que tenhamos certeza de que um programa está correto para casos de teste de parâmetros pequenos (isto é, não teóricos) que se generalizam claramente para dar uma resposta correta.
res

11
É mais longo, mas se você quiser usar eval vez de exec, sua última linha pode ser f=lambda x:A(x,x);print eval('f('*x+'x'+')'*x). Além disso, sua definição de A (m, n) precisa ser corrigida pelo comentário do boothby.
res

2

Ruby, 54 52 50 bytes

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

Rubi, 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]

Hierarquia em rápido crescimento com 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]

Basicamente, uma função de Ackermann com uma torção.


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

Outro 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

Basicamente, Ackermann funciona 99 vezes.


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

Que talvez pudesse ser reduzido para 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)

Onde X existe um número grande apropriado, de modo que a hiperoperação resultante 3, 3seja maior que o número de Grahams (se esse número for menor do que 99999999999algum byte será salvo).


Nota: Presumo que o código python seja executado no interpretador interativo, portanto, o resultado será impresso em stdout; caso contrário, adicione 9bytes a cada solução para a qual a chamada será feita print.


2
Sua solução de 74 bytes não produz uma saída suficientemente grande.
precisa saber é o seguinte

0

Javascript, 83 bytes

Outra solução da função 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 bytes, porém pouco atraente para usar o 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 A função é semelhante à notação de seta para cima na 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

ba função é: b (x) = b x (9).

b(99)é ~ f ω + 1 (99), comparado ao número de Graham <f ω + 1 (64).


Se você marcou isso como não concorrente devido ao fato de o idioma ser mais novo que a questão, você não precisa mais fazer isso
Jo King
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.