You may want to consider something like memoize to speed up recursive functions by using more memory. Essentially it stores the results of any call in a cache.
Add the following code
import collections
import functools
class memoized(object):
'''Decorator. Caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned
(not reevaluated).
'''
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
if not isinstance(args, collections.Hashable):
# uncacheable. a list, for instance.
# better to not cache than blow up.
return self.func(*args)
if args in self.cache:
return self.cache[args]
else:
value = self.func(*args)
self.cache[args] = value
return value
def __repr__(self):
'''Return the function's docstring.'''
return self.func.__doc__
def __get__(self, obj, objtype):
'''Support instance methods.'''
return functools.partial(self.__call__, obj)
Then decorate your function like this
@memoized
def fun(x1, y1, x2, y2, n, r=[]):
...
Also be careful with your optional parameter. The list created by r = []
will actually be shared across all calls of f with an r. It is better to do something like this so a new list is created every time.
def fun(x1, y1, x2, y2, n, r=None):
r = [] if r is None else r
A more Pythonic way of getting the length is like this
print len(fun(200, 400, 200, 0, 9))