2016-02-21 12 views
10

Zakładając, że komputer działa ten program ma nieskończoną ilość pamięci, jestem zainteresowany w którym Python pęknie podczas pracy, co następuje:Jakie ograniczenia techniczne uniemożliwiają obliczenie liczby Grahama w pythonie?

Dla zabawy, I wdrożone hyperoperators w python jako moduł hyperop. Jeden z moich przykładów jest Liczba Grahama:

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

Skrócone wersja klasy hyperop wygląda następująco:

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

Zasadniczo biblioteka jest tylko rekurencyjne krotnie prawym operacji, ze szczególnym definicji base case of n=1. Pierwotnie __call__ było pięknie grałem jako:

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

Jednak it turns out that you can't make a list with more elements than the size of a C long. Było to zabawne ograniczenie, którego większość programistów w Pythonie prawdopodobnie nie napotkało na co dzień, co zainspirowało następujące pytanie.

przypadku, jeśli w ogóle, będzie obliczenie hyperop niepowodzeniem ze względu na ograniczenia techniczne pytona (konkretnie 2.7.10)?

+5

Jako że "obserwowalny wszechświat jest o wiele za mały, by pomieścić zwykłą cyfrową reprezentację numeru Grahama" *, powiem "nie". Najważniejsza wskazówka: jeśli musisz zacząć od * "jest to uzasadnione pytanie" * prawdopodobnie masz rację! – jonrsharpe

+0

Czy pytanie dotyczy użycia 'yield' i" sekwencji nieskończonych ", lub czegoś, co można przypiąć bardziej zwięźle? – user2864740

+0

Ograniczenie większej liczby elementów niż rozmiar C jest wspomniane tylko w Pythonie 2. .... – PascalVKooten

Odpowiedz

1

Może oryginalna wersja hyperop jest solidna i nie z powodu jakiejś ezoterycznej ale dokładna przyczyna tego kodu nie powiedzie się, ponieważ konstruktor hyperop nazywa się i podnosi RuntimeError z „maksymalna głębokość rekursji przekroczone” (po sys.setrecursionlimit wywołań rekurencyjnych - prawdopodobnie domyślnie 1000 w 2.7.10).

Powiązane problemy