Функция Аккермана известна тем, что является одним из простейших примеров полной вычислимой функции, которая не является примитивно-рекурсивной.
Мы будем использовать определение A(m,n)
взятия двух неотрицательных целых чисел, где
A(0,n) = n+1
A(m,0) = A(m-1,1)
A(m,n) = A(m-1,A(m,n-1))
Вы можете реализовать
- именованная или анонимная функция, принимающая в качестве входных данных два целых числа, возвращающая целое число, или
- программа, получающая два целых числа, разделенных пробелом или новой строкой, в STDIN и выводит результат в STDOUT.
Вы не можете использовать функцию Аккермана или функцию гиперэкспонирования из библиотеки, если она существует, но вы можете использовать любую другую функцию из любой другой библиотеки. Допускается регулярное возведение в степень.
Ваша функция должна быть в состоянии найти значение A(m,n)
для m ≤ 3 и n ≤ 10 менее чем за минуту. Он должен, по крайней мере, теоретически завершаться на любых других входах: учитывая бесконечное пространство стека, собственный тип Bigint и произвольно длительный период времени, он будет возвращать ответ. Изменить: Если ваш язык имеет глубину рекурсии по умолчанию, которая слишком ограничительна, вы можете перенастроить ее без затрат на символы.
Представление с кратчайшим количеством символов выигрывает.
Вот некоторые значения, чтобы проверить ваш ответ:
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)
и выше, чем наивно, как другие? Нужно ли придумывать решение без рекурсии, или я могу просто «предполагать бесконечное пространство в стеке» в этих случаях? Я уверен, что это закончится в течение минуты.