Programma di chiusura più breve la cui dimensione di output supera il numero di Graham


37

Scrivi il programma più breve possibile (lunghezza misurata in byte) che soddisfi i seguenti requisiti:

  • nessun input
  • l'output è su stdout
  • l'esecuzione alla fine termina
  • il numero totale di byte di output supera il numero di Graham

Supponiamo che i programmi vengano eseguiti fino alla terminazione "normale" su un computer ideale 1 in grado di accedere a risorse illimitate e che i linguaggi di programmazione comuni vengano modificati, se necessario (senza cambiare la sintassi), per consentire ciò. A causa di questi presupposti, potremmo chiamarlo una sorta di esperimento di Gedankene.

Per iniziare, ecco un programma Ruby a 73 byte che calcola f ω + 1 (99) nella gerarchia in rapida crescita :

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 MODIFICA: Più precisamente, supponiamo di prendere un sistema esistente e di modificarlo solo per non avere limiti massimi sulle dimensioni di archiviazione (ma è sempre finito). I tempi di esecuzione delle istruzioni non dovrebbero essere modificati, ma si presume che la macchina sia ideale in quanto non avrà limiti superiori per la sua durata operativa.


Questo porta la mia domanda sulla tetrazione a un livello completamente nuovo!
MrZander

1
C'era una volta un concorso di programmazione simile chiamato Bignum Bakeoff. Alcune voci sono piuttosto interessanti; i risultati sono qui: djm.cc/bignum-results.txt
Danny Chia

Risposte:


11

GolfScript ( 49 47 caratteri)

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

Vedi Lifetime of a worm per molte spiegazioni. In breve, questo stampa un numero maggiore di f ω ω (2).


f_ (ω ^ ω) (2) è grande circa quanto g_ (f_8 (8)), quindi non eccessivo come implicherebbe quell'espressione.
Semplicemente bellissimo 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

Come funziona: %prende semplicemente una funzione e la compone più n-1volte s; cioè %3prende una funzione fe restituisce una funzione nche equivale ad applicarla fa 3, n-1volte di fila. Se ripetiamo l'applicazione di questa funzione di ordine superiore, otteniamo una sequenza di funzioni in rapida crescita - a partire dall'esponenziazione, è esattamente la sequenza delle dimensioni della foresta-freccia-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 così via. ((%3)%(3^))n 3è 3 ↑ⁿ 3, che è ciò che appare nel calcolo al numero di Graham. Tutto ciò che resta da fare è comporre la funzione(\n -> 3 ↑ⁿ 3) ≡ flip((%3)%(3^))3più di 64 volte, in cima a 4 (il numero di frecce con cui inizia il calcolo), per ottenere un numero maggiore del numero di Graham. È ovvio che il logaritmo (che funzione debolmente lenta è!) g₆₅È ancora maggiore di g₆₄=G, quindi se stampiamo quel numero la lunghezza dell'output supera G.


Quando lo collaudo con print$((flip((%3)%(3*))3)%2)1, c'è un errore di runtime - puoi dire perché? Ha esito positivo quando 2viene modificato in 1(l'output è 81).
ris.

Oh ... ideone sembra funzionare con una versione a 32 bit, quindi arriva a un overflow di Intrapidamente. Su un sistema a 64 bit, che consuma troppa memoria per la riproduzione, ma ovviamente non consente di raggiungere G. Ho bisogno del tipo (big-int) Integer, quindi non posso usarlo !!; aspetta ...
cessò di girare in senso antiorario

Risolto il problema ora, ho dovuto utilizzare la ricorsione esplicita per implementare %.
cessò di girare in senso antiorario il

Trovo che in ((%3)%(3*))2 nrealtà cresca più velocemente di quanto dici (una buona cosa), ma il mio Haskell-fu è inadeguato per capire il perché. Perché n = 0, 1, 2, ..., invece di dare 3, 3^3, 3^(3^3), ..., dà 3, 3^(3+1), 3^((3^(3+1))+1), ....
res

Come ho detto: " ((%3)%(3*))n 3è più grande di 3 ↑ⁿ 3". O intendi qualcos'altro? Ad ogni modo, ho cambiato la definizione in modo che siano tutte uguaglianze (almeno penso di sì, per essere pigro da controllare ora ...) piuttosto che per i più grandi. E se cambi 66a 65, in realtà si produce da Gsolo, non è carino?
cessò di girare in senso antiorario il

5

Pyth , 29 28 byte

M?*GHgtGtgGtH^ThH=ZTV99=gZTZ

Definisce un lambda per iper-operazione e lo chiama in modo ricorsivo. Come la definizione del numero di Graham, ma con valori più grandi.

Questo:

M?*GHgtGtgGtH^3hH

Definisce un lambda, approssimativamente uguale al pitone

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

Questo dà la funzione di iper-operazione, g (G, H) = 3 ↑ G + 1 (H + 1).
Quindi, ad esempio, g (1,2) = 3 ↑ 2 3 = 7.625.597.484.987, che puoi testare qui .

V<x><y>avvia un ciclo che esegue il corpo y, xvolte.
=gZTè il corpo del loop qui, che equivale aZ=g(Z,10)

Il codice:

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

Dovrebbe chiamare ricorsivamente l'iperoperazione oltre 64 volte, dando il numero di Graham.

Nella mia risposta, tuttavia, ho sostituito le singole cifre con T, che è inizializzato a 10, e aumentato la profondità della ricorsione a 99. Usando Graham Array Notation , Graham's Number è [3,3,4,64] e il mio il programma genera il più grande [10,11,11,99]. Ho anche rimosso l' )elemento che chiude il ciclo per salvare un byte, quindi stampa ogni valore successivo nelle 99 iterazioni.


3

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

Anche se questo non è breve come il programma Ruby del risponditore, lo posterò comunque, per escludere questa possibilità.

Utilizza la funzione Ackermann e chiama la funzione Ackermann con m e n che sono i valori di un'altra chiamata alla funzione Ackermann e ricorre 1000 volte.

Questo è probabilmente più grande del numero di Graham, ma non ne sono sicuro, perché nessuno ne conosce la lunghezza esatta. Può essere facilmente esteso, se non è più grande.

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

uscita su stdout? inoltre, hai bisogno di una returndichiarazione o un lambda.
stand dal

7
Anche se A (m, n) restituisce un singolo valore, allora A (A (5,5)) non manca un argomento? ... Questo è il problema con una sfida come questa: incoraggia le persone a non testare il loro codice, perché una corsa completa è puramente teorica.
breadbox,

Se sostituisci l'ultima riga con exec'x=A(x,x);'*x;print x, allora il programma è ok e l'output è approssimativamente f_ (ω + 1) (x) (supponendo che il codice della funzione Ackermann sia corretto), che ha più di G byte anche per x = 99, ad esempio . (Nel mio programma Ruby, f[m,n]è una versione di A(m,n).)
ris.

@breadbox - Buon punto ... Domande teoriche come questa ci richiedono di assicurarci che un programma sia ok per casi di test di piccolo parametro (cioè non teorici) che si generalizzano chiaramente per dare una risposta corretta.
res

1
È più lungo, ma se si desidera utilizzare al evalposto di exec, potrebbe essere l'ultima riga f=lambda x:A(x,x);print eval('f('*x+'x'+')'*x). Inoltre, la tua def di A (m, n) deve essere corretta in base al commento della cabina.
res

2

Rubino, 54 52 50 byte

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

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

Gerarchia praticamente in rapida crescita con f (a + 1)> f ω + 1 (a).


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

Fondamentalmente una funzione di Ackermann con una svolta.


Rubino, 63 59 byte

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

Un altro rubino, 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

Fondamentalmente Ackermann funziona da solo 99 volte.


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

Che forse potrebbe essere abbreviato in 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)

Dove Xc'è un numero grande appropriato tale che l'iperoperazione risultante su 3, 3sia maggiore del numero di Grahams (se questo numero è inferiore a 99999999999qualche byte viene salvato).


Nota: suppongo che il codice Python sia eseguito sull'interprete interattivo, quindi il risultato viene stampato su stdout, altrimenti aggiungere 9byte a ciascuna soluzione per la chiamata a print.


2
La tua soluzione a 74 byte non produce un output abbastanza grande.
lirtosiast,

0

Javascript, 83 byte

Un'altra soluzione funzionale 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 byte, tuttavia non competitivo per l'utilizzo di 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 la funzione è simile alla notazione con la freccia in su con 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

bla funzione è: b (x) = b x (9).

b(99)è ~ f ω + 1 (99), rispetto al numero di Graham <f ω + 1 (64).


Se hai contrassegnato questa non competizione a causa della lingua più recente della domanda, non devi più farlo
Jo King
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.