Funkcja Ackermanna wyróżnia się jako jeden z najprostszych przykładów całkowitej, obliczalnej funkcji, która nie jest prymitywną rekurencyjną.
Użyjemy definicji A(m,n)
przyjmowania dwóch nieujemnych liczb całkowitych gdzie
A(0,n) = n+1
A(m,0) = A(m-1,1)
A(m,n) = A(m-1,A(m,n-1))
Możesz wdrożyć
- nazwana lub anonimowa funkcja przyjmująca dwie liczby całkowite jako dane wejściowe, zwracająca liczbę całkowitą lub
- program przyjmujący dwie liczby całkowite oddzielone spacją lub znakiem nowej linii na STDIN, drukujący wynik do STDOUT.
Nie możesz używać funkcji Ackermanna ani funkcji hipereponentyzacji z biblioteki, jeśli taka istnieje, ale możesz użyć dowolnej innej funkcji z dowolnej innej biblioteki. Dozwolone jest regularne potęgowanie.
Twoja funkcja musi być w stanie znaleźć wartość A(m,n)
dla m ≤ 3 in ≤ 10 w mniej niż minutę. Musi przynajmniej teoretycznie kończyć się na innych wejściach: biorąc pod uwagę nieskończoną przestrzeń stosu, natywny typ Biginta i dowolnie długi okres czasu, zwróci odpowiedź. Edycja: Jeśli Twój język ma domyślną głębokość rekurencji, która jest zbyt restrykcyjna, możesz ją ponownie skonfigurować bez żadnych kosztów znaków.
Zgłoszenie z najmniejszą liczbą znaków wygrywa.
Oto kilka wartości, aby sprawdzić swoją odpowiedź:
A | n=0 1 2 3 4 5 6 7 8 9 10
-----+-----------------------------------------------------------------
m=0 | 1 2 3 4 5 6 7 8 9 10 11
1 | 2 3 4 5 6 7 8 9 10 11 12
2 | 3 5 7 9 11 13 15 17 19 21 23
3 | 5 13 29 61 125 253 509 1021 2045 4093 8189
4 | 13 65533 big really big...
A(3,8)
i przewyższyć tak naiwnie jak inne? Czy muszę wymyślić rozwiązanie nierekurencyjne, czy też mogę po prostu „założyć nieskończone miejsce na stosie” w tych przypadkach? Jestem całkiem pewien, że to skończy się w ciągu minuty.