Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

more ruby way of doing project euler #2

Tags:

ruby

I'm trying to learn Ruby, and am going through some of the Project Euler problems. I solved problem number two as such:

def fib(n)
  return n if n < 2
  vals = [0, 1]
  n.times do
    vals.push(vals[-1]+vals[-2])
  end
  return vals.last
end
i = 1
s = 0
while((v = fib(i)) < 4_000_000)
  s+=v if v%2==0
  i+=1
end
puts s

While that works, it seems not very ruby-ish—I couldn't come up with any good purely Ruby answer like I could with the first one ( puts (0..999).inject{ |sum, n| n%3==0||n%5==0 ? sum : sum+n }).

like image 281
Aaron Yodaiken Avatar asked Dec 29 '22 14:12

Aaron Yodaiken


2 Answers

For a nice solution, why don't you create a Fibonacci number generator, like Prime or the Triangular example I gave here.

From this, you can use the nice Enumerable methods to handle the problem. You might want to wonder if there is any pattern to the even Fibonacci numbers too.

Edit your question to post your solution...

Note: there are more efficient ways than enumerating them, but they require more math, won't be as clear as this and would only shine if the 4 million was much higher.

As demas' has posted a solution, here's a cleaned up version:

class Fibo
  class << self
    include Enumerable

    def each
      return to_enum unless block_given?
      a = 0; b = 1
      loop do
        a, b = b, a + b
        yield a
      end
    end
  end
end

puts Fibo.take_while { |i| i < 4000000 }.
          select(&:even?).
          inject(:+)
like image 80
Marc-André Lafortune Avatar answered Jan 17 '23 01:01

Marc-André Lafortune


My version based on Marc-André Lafortune's answer:

class Some
  @a = 1
  @b = 2

  class << self
    include Enumerable

    def each
      1.upto(Float::INFINITY) do |i|
        @a, @b = @b, @a + @b
        yield @b
      end
    end
  end
end

puts Some.take_while { |i| i < 4000000 }.select { |n| n%2 ==0 }
          .inject(0) { |sum, item| sum + item } + 2
like image 39
ceth Avatar answered Jan 17 '23 00:01

ceth