Ibonacci sequence problem

Hello,

I have this problem.

By considering the terms in the Fibonacci sequence whose values do not
exceed four million, find the sum of the even-valued terms.

So i was thinking of solving it this way

  1. n = Array.new [1,2]

  2. while n[-1] + n[-2] < 4000000 do
    n << n[-2] + n[-1]
    end

So I have now all the numbers.

  1. n.inject { |sum, number| if number%2 == 0 then sum + number else sum
    end}

I see a answer but according to the site it’s wrong.

Can anyone tell me where I’m thinking wrong ?

Roelof

I got 4_613_732 using

z, s = [0, 1], 0

while (z << (n = z[-1] + z[-2]))[-1] < 4_000_000
s += n if n % 2 == 0
end
p s

=> 4613732

What did they say you should get?

Hi,

Roelof W. wrote in post #1077938:

By considering the terms in the Fibonacci sequence whose values do not
exceed four million, find the sum of the even-valued terms.

The problem is that you (unintentionally) start the sum with 1 instead
of 0. When you don’t set a start value for inject, the aggregate value
is set to the first element. In this case it’s 1, so the result will be
1 too big.

Also your code is rather “naive” in the sense that you’re treating the
numbers as if they were physical objects and actually needed to be
collected. This is very inefficient and completely unnessary. You only
need to track the last two numbers.

You should also get rid of some habits you seem to have adopted from
other programming languages (like Java or so). Things like “Array.new
[1,2]” and “number % 2 == 0” are useless in Ruby. The literal “[1,2]”
already is an array. And checking if an integer is even can be done by
simply calling “even?”.

A low-level solution might look something like this:

previous, current =
0, 1
sum = 0
while current <= 4_000_000
sum += current if current.even?
previous, current =
current, previous + current
end
puts sum

A more high-level approach could consist of defining an Enumerator for
the fibonacci sequence and then apply “take_while”, “select” and
“reduce” subsequently:

fibonacci = Enumerator.new do |yielder|
previous, current =
0, 1
yielder << previous
loop do
yielder << current
previous, current =
current, previous + current
end
end

sum = fibonacci.take_while{|e| e <= 4_000_000}.select(&:even?).reduce :+
puts sum

This actually works similar to your code, so it’s not efficient. But
it’s very readable and kind of “the Ruby way”.

Thanks,

I think learning to programm is difficult without a sort of teacher. You
never get checked if you are doing it the ruby way.
I’m now reading the Well Grounded Rubyist

But that one is without exercises so I can never check if I really
understand it.
And the best way for me to learn something is to do it and not only to
read about it.

Roelof

Roelof W. wrote in post #1077985:

And the best way for me to learn something is to do it and not only to
read about it.

Yes, absolutely! And I think my critique was a bit unjust: You’ve found
a valid, logical solution that works fine (apart from the small “inject”
mistake). So you’ve done a good job.

What I was talking about is the next step: improving the programming
style. When you’ve found a solution, it’s always a good idea to try to
improve it and think about alternative approaches.

For example, you could ask yourself: Do I really need to save all
elements in an array? Or you could look for built-in Ruby methods to
solve the task: How can I create a “sequence object”? How can I select
all elements up to the first one that doesn’t fulfill a condition? etc.

I’ve found this to very helpful in the learning process. Solving a
problem is one thing. Digging deep into the language to find a better
solution is even better.

Roelof W. wrote in post #1078000:

Image I have
this situation.Look for a number which is prime and can be divided by 2.

Is this really the task? Because the only even prime number is 2
(obviously).

Date: Sat, 29 Sep 2012 21:18:16 +0900

Thanks I will try to do that.I have one question about it. Image I have
this situation.Look for a number which is prime and can be divided by 2.
I can do if number == prime and even?number then But as I see it if a
number is not a prime there is no need to look if it’s even.Then I could
do if number == prime if even?number p number endend But
this looks like a long code for the problem. What’s the best ruby way to
solve this ? Roelof

Date: Sat, 29 Sep 2012 20:18:41 +0900