From: Roelof Wobben Date: 2012-09-29T17:02:45+09:00 Subject: Re: ibonacci sequence problem --_0f592ef9-37c3-4a17-bb11-9401f1a7fd45_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Thanks=2C=20 I think learning to programm is difficult without a sort of teacher. You ne= ver 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 understa= nd it. And the best way for me to learn something is to do it and not only to read= about it. Roelof =20 > Date: Sat=2C 29 Sep 2012 10:48:58 +0900 > From: lists@ruby-forum.com > Subject: Re: ibonacci sequence problem > To: ruby-talk@ruby-lang.org >=20 > Hi=2C >=20 > Roelof Wobben wrote in post #1077938: > > By considering the terms in the Fibonacci sequence whose values do not > > exceed four million=2C find the sum of the even-valued terms. >=20 > The problem is that you (unintentionally) start the sum with 1 instead=20 > of 0. When you don't set a start value for inject=2C the aggregate value= =20 > is set to the first element. In this case it's 1=2C so the result will be= =20 > 1 too big. >=20 > Also your code is rather "naive" in the sense that you're treating the=20 > numbers as if they were physical objects and actually need to be=20 > collected. This is very inefficient and completely unnessary. You only=20 > need to track the last two numbers. >=20 > You should also get rid of some habits you seem to have adopted from=20 > other programming languages (like Java or so). Things like "Array.new=20 > [1=2C2]" and "number % 2 =3D=3D 0" are useless in Ruby. The literal "[1= =2C2]"=20 > already *is* an array. And checking if an integer is even can be done by= =20 > simply calling "even?". >=20 > A low-level solution might look something like this: >=20 > previous=2C current =3D > 0=2C 1 > sum =3D 0 > while current <=3D 4_000_000 > sum +=3D current if current.even? > previous=2C current =3D > current=2C previous + current > end > puts sum >=20 > A more high-level approach could consist of defining an Enumerator for=20 > the fibonacci sequence and then apply "take_while"=2C "select" and=20 > "reduce" subsequently: >=20 > fibonacci =3D Enumerator.new do |yielder| > previous=2C current =3D > 0=2C 1 > yielder << previous << current > loop do > previous=2C current =3D > current=2C previous + current > yielder << current > end > end >=20 > sum =3D fibonacci.take_while{|e| e <=3D 4_000_000}.select(&:even?).reduce= :+ > puts sum >=20 > This actually works similar to your code=2C so it's not efficient. But=20 > it's very readable and kind of "the Ruby way". >=20 > --=20 > Posted via http://www.ruby-forum.com/. >=20 = --_0f592ef9-37c3-4a17-bb11-9401f1a7fd45_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
Thanks=2C

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 =3B
the Well Grounded Rubyist

But that one is wi= thout 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 i= t.

Roelof
 =3B


>=3B Date: Sat=2C 29 Sep 2012 10:48:58 +0900
>=3B From= : lists@ruby-forum.com
>=3B Subject: Re: ibonacci sequence problem
= >=3B To: ruby-talk@ruby-lang.org
>=3B
>=3B Hi=2C
>=3B >=3B Roelof Wobben wrote in post #1077938:
>=3B >=3B By consideri= ng the terms in the Fibonacci sequence whose values do not
>=3B >=3B= exceed four million=2C find the sum of the even-valued terms.
>=3B >=3B The problem is that you (unintentionally) start the sum with 1 ins= tead
>=3B of 0. When you don't set a start value for inject=2C the ag= gregate value
>=3B is set to the first element. In this case it's 1= =2C so the result will be
>=3B 1 too big.
>=3B
>=3B Also y= our code is rather "naive" in the sense that you're treating the
>=3B= numbers as if they were physical objects and actually need to be
>= =3B collected. This is very inefficient and completely unnessary. You only =
>=3B need to track the last two numbers.
>=3B
>=3B You sho= uld also get rid of some habits you seem to have adopted from
>=3B ot= her programming languages (like Java or so). Things like "Array.new
>= =3B [1=2C2]" and "number % 2 =3D=3D 0" are useless in Ruby. The literal "[1= =2C2]"
>=3B already *is* an array. And checking if an integer is even= can be done by
>=3B simply calling "even?".
>=3B
>=3B A l= ow-level solution might look something like this:
>=3B
>=3B prev= ious=2C current =3D
>=3B 0=2C 1
>=3B sum =3D 0
>=3B while = current <=3B=3D 4_000_000
>=3B sum +=3D current if current.even?>=3B previous=2C current =3D
>=3B current=2C previous + curr= ent
>=3B end
>=3B puts sum
>=3B
>=3B A more high-level= approach could consist of defining an Enumerator for
>=3B the fibona= cci sequence and then apply "take_while"=2C "select" and
>=3B "reduce= " subsequently:
>=3B
>=3B fibonacci =3D Enumerator.new do |yield= er|
>=3B previous=2C current =3D
>=3B 0=2C 1
>=3B yi= elder <=3B<=3B previous <=3B<=3B current
>=3B loop do
>= =3B previous=2C current =3D
>=3B current=2C previous + curre= nt
>=3B yielder <=3B<=3B current
>=3B end
>=3B end=
>=3B
>=3B sum =3D fibonacci.take_while{|e| e <=3B=3D 4_000_00= 0}.select(&=3B:even?).reduce :+
>=3B puts sum
>=3B
>=3B = This actually works similar to your code=2C so it's not efficient. But
= >=3B it's very readable and kind of "the Ruby way".
>=3B
>=3B = --
>=3B Posted via http://www.ruby-forum.com/.
>=3B
=
= --_0f592ef9-37c3-4a17-bb11-9401f1a7fd45_--