I was wondering if this is the fastest possible version of this function.
(defun foo (x y)
(cond
;if x = 0, return y+1
((zp x) (+ 1 y))
;if y = 0, return foo on decrement x and 1
((zp y) (foo (- x 1) 1))
;else run foo on decrement x and y = (foo x (- y 1))
(t (foo (- x 1) (foo x (- y 1))))))
When I run this, I usually get stack overflow error, so I am trying to figure out a way to compute something like (foo 3 1000000) without using the computer.
From analyzing the function I think it is embedded foo in the recursive case that causes the overflow in (foo 3 1000000). But since you are decrementing y would the number of steps just equal y?
edit: removed lie from comments
Conceptually speaking, stack overflows don't have anything to do with speed, but they concern space usage. For instance, consider the following implementations of
length
. The first will run into a stack overflow for long lists. The second will too, unless your Lisp implements tail call optimization. The third will not. All have the same time complexity (speed), though; they're linear in the length of the list.You can do something similar for your code, though you'll still have one recursive call that will contribute to stack space. Since this does appear to be the Ackermann function, I'm going to use
zerop
instead ofzp
andack
instead offoo
. Thus, you could do:Since
x
is decreasing by1
on each iteration, and the only conditional change is ony
, you could simplify this as:Since
y
is the only thing that conditionally changes during iterations, you could further simplify this to:This is an expensive function to compute, and this will get you a little bit farther, but you're still not going to get, e.g., to
(ackN 3 1000000)
. All these definitions are available for easy copying and pasting from http://pastebin.com/mNA9TNTm.Generally, memoization is your friend in this type of computation. Might not apply as it depends on the specific arguments in the recursion; but it is a useful approach to explore.
12 years ago I wrote this:
As you can see, I am using an explicit formula for small
a
and memoization for largera
.Note, however, that this function grows so fast that it makes little sense to try to compute the actual values; you will run out of atoms in the universe faster - memoization or not.