Reputation: 45
In Python:
def g(n):
if n <=3:
return n
return g(n-1) + 2 * g(n-2) + 3 * g(n-3)
I understand what this function is doing, but I can't seem to get how to make it iterative. Help, please. If possible, please include an explanation so that I could fully understand the problem.
Upvotes: 1
Views: 2545
Reputation: 20718
This looks similar to the fibonacci series problem and is non-trivial to implement in an iterative fashion. It also looks like homework, so I will be posting the steps to get fibonacci iterative and you should be able to apply that to your problem.
In case you do not know, fibonacci is defined like this:
def fib(n):
if n <= 1: # technically, this is not 100% correct, but it's fine for n>=0
return n
return fib(n-1) + fib(n-2)
So let's analyze fib(n)
. First we see that there are two different cases: n <= 1
and not n <= 1
. For n <= 1
, fib(n)
has no dependencies, so we can just evaluate that:
def fib_iter(n):
if n <= 1:
return n
Now we need to cover the other case. Let's first do a dependency analysis. What do we need for fib(n)
with n > 1
? We call to fib(n-1)
and fib(n-2)
. In iterative language, these would be the two previous values. So obviously, we need to keep track of those. We will start with the two trivial cases on that one:
def fib_iter(n):
if n <= 1:
return n
prev1, prev2 = 0, 1
I hope this is rather obvious. Then we resolve the functions in the order they are resolved in the recursive approach. When unwinding the recursion and analyzing the function, we find that the first non-trival value which will be evaluated is of course fib(2)
. Then fib(3)
and so on until we reach n
. Due to the recursive approach, several values are evaluated multiple times, but we do not need that in an iterative approach. The values are added together, which gives us the following code:
def fib_iter(n):
if n <= 1:
return n
prev1, prev2 = 0, 1
for i in xrange(2, n+1):
curr = prev1 + prev2 # calculate fib(i)
prev1, prev2 = prev2, curr # shift previous value cache
The only thing which is missing is the return value, which is just curr
at the time the loop ends. As we do xrange(2, n+1)
and check for n <= 1
in advance, the loop will run at least once, so curr
will be defined outside the loop.
def fib_iter(n):
if n <= 1:
return n
prev1, prev2 = 0, 1
for i in xrange(2, n+1):
curr = prev1 + prev2
prev1, prev2 = prev2, curr
return curr
(this is my first homework answer; the SO community might give me feedback what I could've done better if I spoiled too much)
Upvotes: 8
Reputation: 56654
Your recursive function can be read as
To find the value of g(30), find the value of g(29), g(28), and g(27)
To find the value of g(29), find the value of g(28), g(27), and g(26)
To find the value of g(28), find the value of g(27), g(26), and g(25)
...
(repeat until all sub-finds have completed)
An iterative function would start at the other end,
I know the values of g(1), g(2), and g(3) -> calculate g(4)
I know the values of g(2), g(3), and g(4) -> calculate g(5)
I know the values of g(3), g(4), and g(5) -> calculate g(6)
...
(repeat until the desired g(n) is reached)
Upvotes: 3
Reputation: 2491
def g(n):
if n <= 3:
return n
a, b, c = 1, 2, 3
for i in range(3, n):
a, b, c = b, c, (a * 3 + b * 2 + c)
return c
Upvotes: 4
Reputation: 22001
This was too much fun not to solve ...
def g(n, *, _cache=[0, 1, 2, 3]):
for _ in range(n - len(_cache) + 1):
_cache.append(sum(i * _cache[-i] for i in (1, 2, 3)))
return _cache[n]
Hopefully, you will have already found a solution.
Upvotes: 1