Reputation: 170
I am given this function and asked to manually evaluate g 5
. I found the answer to be 25, but this is incorrect. The correct answer is 63. Would anyone help me understand why? Thanks
g :: Int -> Int
g n
| n==0 = 1
| otherwise = 2 * g (n-1) + 1
My answer: (2*4+1) + (2*3+1) + (2*2+1) + (2*1+1) + 1 = 25
Upvotes: 1
Views: 428
Reputation: 45736
You just need to think it out step by step:
(g 5) = 2 * (g 4) + 1
(g 4) = 2 * (g 3) + 1
(g 3) = 2 * (g 2) + 1
(g 2) = 2 * (g 1) + 1
(g 1) = 2 * (g 0) + 1
(g 0) = 1
Then, plug in the values from the bottom-up:
2 * 1 + 1 = 3
2 * 3 + 1 = 7
2 * 7 + 1 = 15
2 * 15 + 1 = 31
2 * 31 + 1 = 63
Your problem is that you were using the raw value of n
, instead of what (g n)
returned at the end of the recursion.
Upvotes: 8
Reputation: 4635
Your parenthesization is wrong. Not doing any reductions (other than expanding g
), we get
g 5
= 2 * g 4 + 1
= 2 * (2 * g 3 + 1) + 1
= 2 * (2 * (2 * g 2 + 1) + 1) + 1
= 2 * (2 * (2 * (2 * g 1 + 1) + 1) + 1) + 1
= 2 * (2 * (2 * (2 * (2 * g 0 + 1) + 1) + 1) + 1) + 1
= 2 * (2 * (2 * (2 * (2 * 1 + 1) + 1) + 1) + 1) + 1
Upvotes: 0
Reputation: 2738
Although this isn't your question, it's fairly easy to show by induction that
g n = 2^(n+1)-1
So
g 5 = 2^6 - 1 --> 63
Upvotes: 0
Reputation: 2366
In your calculation you messed up with the nesting of the terms. They should be nested and not summed up separately.
The way to evaluate such functions is to replace function applications with the body of the function with its parameters replaced by the given arguments. I will do the first few steps and then you can take over:
g 5
if 5 == 0 then 1 else 2 * g (5-1) + 1
2 * g (5-1) + 1
2 * (if (5 - 1) == 0 then 1 else 2 * g ((5-1) - 1) + 1) + 1
2 * (if 4 == 0 then 1 else 2 * g (4-1) + 1) + 1
2 * (2 * g (4-1) + 1) + 1
...
63
@Carcigenicate's answer is of course easier to calculate, but this technique is more universal and more inline with how the code actually works.
Upvotes: 2