2016-02-21 4 views
10

Supponendo che il computer che esegue questo programma ha una quantità infinita di memoria, mi interessa dove Python si rompe quando si esegue il seguente:Quali limitazioni tecniche impediscono il calcolo del numero di Graham in python?

Per divertimento, ho implementato hyperoperators in python come modulo hyperop. Uno dei miei esempi è il numero di Graham:

def GrahamsNumber(): 
    # This may take awhile... 
    g = 4 
    for n in range(1,64+1): 
     g = hyperop(g+2)(3,3) 
    return g 

La versione condensata della classe hyperop assomiglia a questo:

def __init__(self, n): 
    self.n = n 
    self.lower = hyperop(n - 1) 

def _repeat(self, a, b): 
    if self.n == 1: 
     yield a 

    i = 1 
    while True: 
     yield a 
     if i == b: 
      break 
     i += 1 

def __call__(self, a, b): 
    return reduce(lambda x, y: self.lower(y, x), self._repeat(a, b)) 

In sostanza la biblioteca è solo un'operazione ricorsiva piega a destra, con una definizione speciale per il base case of n=1. Originariamente __call__ era ben giocato a golf come:

return reduce(lambda x, y: self.lower(y, x), [a,]*b) 

Tuttavia, it turns out that you can't make a list with more elements than the size of a C long. Questa è stata una divertente limitazione che la maggior parte dei programmatori Python probabilmente non incontrano nel loro normale giorno per giorno e ha ispirato la seguente domanda.

Dove, se non del tutto, sarà il calcolo hyperop fallire a causa di una limitazione tecnica di pitone (specificamente 2.7.10)?

+5

Come * "l'universo osservabile è troppo piccolo per contenere una normale rappresentazione digitale del numero di Graham" *, ho intenzione di dire di no. Suggerimento: se devi iniziare con * "questa è una domanda legittima" * probabilmente ti sbagli! – jonrsharpe

+0

La domanda sull'uso di 'yield' e" infinite sequenze "o qualcosa che può essere riassunta in modo più sintetico? – user2864740

+0

La limitazione di più elementi rispetto alla dimensione di un C lungo è menzionata solo per Python 2 .... – PascalVKooten

risposta

1

versione originale del Forse hyperop è robusto e non riesce a causa di qualche causa esoterica ma questo codice esatto non riesce a causa costruttore hyperop si autodefinisce e solleva RuntimeError con "profondità massima di ricorsione superato" (dopo sys.setrecursionlimit di chiamate ricorsive - che è 1000 in 2.7.10 di default probabilmente).

Problemi correlati