Fibonacci find the nth term Ruby - ruby

I understand how fibonacci works but I need an explanation as to why this code works with fib in it vs fib without
def fib(n)
return 1 if n <= 2
return fib(n-1) + fib(n-2)
end
the code above gives the correct answer with fib(n-1) + fib(n-2)
BUT why does this code below not work?
def fib(n)
return 1 if n <= 2
return (n-1) + (n-2)
end

First, welcome to the recursion man !
From now, i bet you always use a function as follow:
function something()
{
//do_something
return (something)
}
It's called iterative function, start and return of the function
But fibonnacci is good example to introduce the concept of recursion!
If you understand fibonnacci you realize that a value is provided by previous value
n + 1 = n / 2 it's a suite.
With that in mind, a function can call it self , yep you heard me,
function something()
{
something();
}
this bit of code will call something forever until you get the famous error "stack overflow" (this website name comes from this error) but you will understand why later.
For now focus on the fact that fib will call it self n times depends on the value you want.
so by removing de return fib(n-1) + fib(n-2) by return (n-1) + (n-2) you only execute this function "once", take this example, for fib if you need to call fib function 5 times but you called fib only once, you failed, that's not what you are asked for.
Thus, calling the same function inside the same one, you can have a taste of what is recursion, take a look on google, and test it !

Related

When calculating the factorial why does this recursive method not work?

Can someone help me understand why the code below works fine
Works:
def factorial(n)
return 1 if n == 1
n * factorial(n-1)
end
puts factorial(5)
But when I refactor it like so, it throws an exception: *': nil can't be coerced into Integer (TypeError)
Fails:
def factorial(n)
puts n
n * factorial(n-1) unless n == 1
end
factorial(5)
As another example, this code works fine and is written in a similar way:
Works:
def count_down(number)
puts number
count_down(number - 1) unless number == 0
end
count_down(10)
this code works fine and is written in a similar way
No it isn’t. Your count_down isn’t similar at all, because it doesn’t return a value.
But your factorial does return a value, and each recursive call uses that value.
Well, your second example doesn’t say what to return when n is 1, so it returns nil and the call stack breaks down.
Your first example does say what to return when n is 1. That’s the difference.

algorithm - Searching for an input for which a function returns a specific value

I have the following function:
F(0) = 0
F(1) = 1
F(2) = 2
F(2*n) = F(n) + F(n+1) + n , n > 1
F(2*n+1) = F(n-1) + F(n) + 1, n >= 1
I am given a number n < 10^25 and I have to show that exists a value a such as F(a)=n. Because of how the function is defined, there might exist a n such as F(a)=F(b)=n where a < b and in this situation I must return b and not a
What I have so far is:
We can split this function into two strict monotone series, one for F(2*n) and one for F(2*n+1) and can find the specified value in logarithmic time, so the finding is more or less done.
I've also found that F(2*n) >= F(2*n+1) for any n, so I first search for it in F(2*n) and if I don't find it there, I search in F(2*n+1)
The problem is calculating the function value. Even with some crazy memoization up to 10^7 and then falling back to recursion, it still couldn't calculate values above 10^12 in a reasonable time.
I think I have the algorithm for actually finding what I need all figured out, but I can't calculate F(n) fast enough.
Simply use memoisation all the way up to the target value, e.g. in Python:
class Memoize:
def __init__(self, fn):
self.fn = fn
self.memo = {}
def __call__(self, *args):
if not self.memo.has_key(args):
self.memo[args] = self.fn(*args)
return self.memo[args]
#Memoize
def R(n):
if n<=1: return 1
if n==2: return 2
n,rem = divmod(n,2)
if rem:
return R(n)+R(n-1)+1
return R(n)+R(n+1)+n
This computes the answer for 10**25 instantly.
The reason this works is because the nature of the recursion means that for a binary number abcdef it will only need to at most use the values:
abcdef
abcde-1,abcde,abcde+1
abcd-2,abcd-1,abcd,abcd+1,abcd+2
abc-2,abc-1,abc,abc+1,abc+2
ab-2,ab-1,ab,ab+1,ab+2
a-2,a-1,a,a+1,a+2
At each step you can move up or down 1, but you also divide the number by 2 so the most you can move away from the original number is limited.
Therefore the memoised code will only use at most 5*log_2(n) evaluations.

I am having trouble understanding this lambda calculus from Understanding Computation

In Tom Stuart's book Understanding Computation, there is a chapter devoted to rebuilding FizzBuzz through Procs/Lambdas. He begins by talking about how to define numbers through procs, and shows that a 'number' could be represented by a proc that is run x number of times for the number it represents (i.e., 1 is proc[x], 2 is proc[proc[x]], etc). That makes sense. However, the next bit he defines a to_integer method as such:
def to_integer(proc)
proc[-> n { n + 1 }][0]
end
This has broken my brain. I cannot make sense of what this means. I have admittedly not worked with procs much, other than lambdas in scope while working with rails.
I can simplify it to
def to_integer(proc)
proc[Proc.new(n){ n + 1 }][0]
end
...but that is as far as I can seem to get. Can anyone explain or simplify this in a way that is easier to understand? What is going on here? I'm confused by the proc[x][0] style, where n is coming from. I am just having a very tough time understanding this.
In the book, the procs being passed to this method are like so:
ZERO = -> p { -> x { x } }
ONE = -> p { -> x { p[x] } }
TWO = -> p { -> x { p[p[x]] } }
The code in to_integer chains 2 proc calls using Ruby's [] shorthand for calling a proc.
It's helpful to walk through it by hand in IRB. Lets start by defining ZERO(a lambda):
ZERO = -> p { -> x { x } }
=> #<Proc:0x007ff86a147930#(irb):103 (lambda)>
You will see different numbers here but the important part is that ZERO is a lambda, which is a proc.
Let's give the anonymous lambda in to_integer a name to make it clear what's going on there. Using the "stabby lambda" syntax:
INCR = -> n { n + 1 }
INCR[2]
=> 3
INCR[3]
=> 4
We send in a number, it returns that number plus 1.
We then pass ZERO into to_integer and it starts things off by calling the lambda ZERO and sending in INCR:
ZERO[INCR]
=> #<Proc:0x007ff86a0decf0#(irb):103 (lambda)>
As you can see this returns another lambda(the one defined in ZERO where p is set to INCR). We can now start the ball rolling by calling this lambda and sending in 0:
ZERO[INCR][0]
=> 0
A proc literal has the syntax "-> parameters { body }". An concrete example of a proc literal to increment a number is "-> n { n + 1 }". For readability, a proc literal can be assigned to a variable, e.g. "INCREMENT = -> n { n + 1 }".
A proc literal can be called by using square brackets "-> parameters { body }[arguments]". Using the previous example, here's how to increment 9 to give you 10 "-> n { n + 1 }[9]". The passed in argument "9" is represented by the parameter "n" in the body, and 1 is added to "n" to give the result. Again, for readability, "INCREMENT[9]" can be used to give the same result.
Now let's look at "ZERO = -> p { -> x { x } }". When "ZERO[INCREMENT][0]" is executed, the "ZERO[INCREMENT]" part is executed first. The result is "-> x { x }" and, by substitution, the original statement becomes "-> x { x }[0]". When that is executed, it returns a 0.
Now let's look at "ONE = -> p { -> x { p[x] } }". When "ONE[INCREMENT][0]" is executed, the "ONE[INCREMENT]" part is executed first. The result is "-> x { p[x] }" where p is "INCREMENT". By substitution, the original statement becomes "-> x { INCREMENT[x] }[0]". When that is executed, basically INCREMENT is called with 0, i.e. "INCREMENT[0]", and the result is 1.
Finally, let's look at:
def to_integer(proc)
proc[-> n { n + 1 }][0]
end
"to_integer(ZERO)" executes "ZERO[-> n { n + 1 }][0]". Note that "-> n { n + 1}" is the same as INCREMENT, so that execution is the same as ZERO[INCREMENT][0]. And as stated above, that produces 0.
"to_integer(ONE)" executes "ONE[-> n { n + 1 }][0]". Note that "-> n { n + 1}" is the same as INCREMENT, so that execution is the same as ONE[INCREMENT][0]. And as stated above, that produces 1.
The same process can be applied to TWO, etc.
Well the base idea here actually came from constructing natural numbers as in Peano Axioms (http://en.wikipedia.org/wiki/Peano_axioms)
Therefore zero is 0, one is S(0), two is S(S(0)), three is S(S(S(0))) etc (where S is some function).
Secondly this method may be rewritten, substituting [] for call:
def to_integer(proc)
proc.call(Proc.new { |n| n + 1 }).call(0)
end
And we can see now clearly it does reverse computation - when we try to count how many is one (which actually is S(0), or in our notation -> p { -> x { p[x] } } which is equivalent to Proc.new { |p| Proc.new { |x| p.call(x) } }, it stores information about that it needs to S(x), where is something we don't know (argument of our proc)
And now is the tricky part. Here Ruby calls our definition of one (it's a Proc, so it can be called!) passing as argument another Proc - this one is equivalent to S function (n + 1). So before final .call(0) we have sequence of Procs - calling deeper one with argument increased by 1 (because of our integer) - S(x). And by final call(0) we set base of our natural numbers S(0).
Maybe it will be helpful to consider some examples:
What number we will get when we substitute to_integer with:
def to_integer(proc)
proc[-> n { n + 1 }][0]
end
(it may be interesting that this numbers are as good natural numbers as standard one).
What will happen if we change the base in call, from 0 to 1?

Ruby recursion error

Does anyone know why this code:
sum=0
def get_sum n
return sum if n<1
sum=sum+n
get_sum(n-1)
end
get_sum 10
gives me this?
rb:3:in `get_sum': undefined local variable or method `sum' for main:Object (NameError)
from 1.rb:8:in `<main>'
The code makes perfectly sense, and you can understand what it is doing.
Normal variables declared outside a function are not accessible inside the function.
You could prefix sum with $ to make it a global variable (not usually a good idea.)
$sum=0
def get_sum n
return $sum if n<1
$sum=$sum+n
get_sum(n-1)
end
get_sum 10
#= 55
If you have a real test case where you want to do this, I can suggest a suitable approach if you want.
Rather than using a global variable, another method using recursion would be like this (limited by stack depth, I guess):
def get_sum(n)
return n if n < 1
n + get_sum(n - 1)
end
sum = get_sum(10)
If you ever use a Ruby implementation that offers tail call optimization (I don't know of any implementations that do), ProGNOMmers's method would be a bit nicer on the stack, but as is a quick test has both exceeding the maximum stack level around n = 9000 or so. Not that you should be recursing 9000 times or anything.
As #Dogbert wrote, normal variables declared outside a function are not accessible inside
the function.
This is an approach which doesn't use global variables (which are not suited for recursion):
def get_sum(n, sum = 0)
return sum if n<1
get_sum(n-1, sum+n)
end
get_sum(10) #=> 55
You never initialized the variable sum before using it.
You can totally avoid using that variable, since it does nothing:
def get_sum n
return 0 if n<1
get_sum(n-1) + n
end
get_sum 10
You might want to try this :
def get_sum n
return n if n == 0
return n + get_sum(n-1)
end
In this version you don't need to instanciate any global variable ( which is not a good idea ), and you actually perform a regressive sum :)

Return values not working as expected in Ruby in a program that solves fibonacci sequence using dynamic programming

I'm new to ruby so I'm probably making a very newbie mistake here but I tried Googling for an answer and couldn't figure out the reason why this code is giving weird behavior. This code is very simple, and uses basic dynamic programming to store intermediate result to a Hash so it is used later to speed up the computation.
$existingSequence = {0 => 1, 1 => 2}
def fib(n)
if $existingSequence.has_key? n
return $existingSequence.values_at n;
end
if n == 0
return 1;
elsif n == 1
return 2;
end
$existingSequence[n] = fib(n - 1) + fib(n - 2)
return $existingSequence[n];
end
n = fib(2)
puts n
I expect this code to output 3 since that makes a call to fib(1) and fib(0) which returns 2 and 1 respectively, and then added to be 3. But the output is 1 and 2.
Hash.values_at returns an array, so when the code does fib(1) + fib(0), it's concatenating the arrays [2] and [1] together, resulting in the answer [2, 1]. Instead of:
return $existingSequence.values_at n;
...you should do this instead:
return $existingSequence[n]
BTW, the Fibonacci sequence traditionally starts with 0 and 1, not 1 and 2.
Slightly off-topic, here's a fun way of doing essentially the same thing, but using the Hash default value mechanism to use the Hash not only for caching, but also for computing the values:
fibs = { 0 => 0, 1 => 1 }.tap do |fibs|
fibs.default_proc = ->(fibs, n) { fibs[n] = fibs[n-1] + fibs[n-2] }
end
fibs[9]
# => 34
Note: I didn't come up with this myself, I stole it from here.
The second line of fib should read:
return $existingSequence[n]
instead of
return $existingSequence.values_at n
Add puts $existingSequence to the end of the file to see the difference.

Resources