# [ACCEPTED]-Fibonacci One-Liner-fibonacci

Score: 79

My favorite solution to this is to use a 3 Hash, the values of which can be determined 2 by an anonymous function:

``````fibonacci = Hash.new{ |h,k| h[k] = k < 2 ? k : h[k-1] + h[k-2] }

fibonacci[6]  # => 8
fibonacci[50] # => 12586269025
``````

It's a "genuine" one-liner 1 and very Ruby-ish.

Score: 19

Using a Ruby 1.9 Enumerator:

``````fib = Enumerator.new do |yielder|
i = 0
j = 1
loop do
i, j = j, i + j
yielder.yield i
end
end

p fib.take_while { |n| n <= 4E6 }
# => [1, 1, 2 ... 1346269, 2178309, 3524578]
``````

As one line:

``````p Enumerator.new { |yielder| i, j = 0, 1; loop {i, j = j, i + j; yielder.yield i} }.take_while { |n| n <= 4E6}
``````

0

Score: 11

``````# Ruby 1.8.7
f = lambda { |x| x < 2 ? x : f.call(x-1) + f.call(x-2) }
puts f.call(6)   #=> 8

# Ruby 1.9.2
f = ->(x){ x < 2 ? x : f[x-1] + f[x-2] }
puts f[6]        #=> 8
``````

0

Score: 8

My favorite is:

``````def fib(n)
(0..n).inject([1,0]) { |(a,b), _| [b, a+b] }[0]
end
``````

0

Score: 6

``````(((1 + 5 ** 0.5) / 2) ** 35 / 5 ** 0.5 - 0.5).to_i / 2
``````

(See this answer for an explanation.)

0

Score: 5

Here's a ruby 2.0 solution, without using 13 inject/reduce which is not lazy:

``````(1..Float::INFINITY).
lazy.
with_object([0,1]).
map { |x, last| last[1] = last[0] + (last[0] = last[1]) }.
select { |x| x % 2 == 0 }.
take_while { |x| x < 4_000_000 }.
reduce(&:+)
``````

I don't 12 particularly like the fibonacci generator, because 11 it doesn't include the initial 0. This solution 10 also takes advantage of the first odd number 9 being F3 (F1 in this sequence generator).

A 8 cleaner (Fibonacci-wise) and correct (In 7 Liber Abaci's definition) solution would 6 be:

``````(1..Float::INFINITY).
lazy.
with_object([0,1]).
map { |x, last| last[1] = last[0] + (last[0] = last[1]);last[0] }.
select { |x| x % 2 == 0 }.
take_while { |x| x < 4_000_000 }.
reduce(&:+)
``````

This solution includes a semi-colon, but 5 I don't know if it counts when used this 4 way :).

[Update]

Here's a proper Fibonacci 3 generator (starting on 0) solution, with 2 no semi-colon (btw, is this a javascript 1 semi-colon wars thingy ?!?) :)

``````(1..Float::INFINITY).
lazy.
with_object([0,1]).
map { |x, last| last[0].tap { last[1] = last[0] + (last[0] = last[1]) } }.
select { |x| x % 2 == 0 }.
take_while { |x| x < 4_000_000 }.
reduce(&:+)
``````
Score: 3

Building on Alex's Hash, this may make you 7 go blind, but it's one line, no semicolons 6 and eliminates the range dependency. the 5 instance_eval trick is very useful for oneliners 4 and golf, although it's horrible Ruby.

``````Hash.new{|h,k|h[k]=k<2?k:h[k-1]+h[k-2]}.update(sum: 0,1=>1).instance_eval {self[:sum]+= self[keys.last+1].even? ? self[keys.last] : 0 while values.last < 4E6 || puts(fetch :sum)}
``````

Outputs: 4613732

I 3 warned you it was horrible. I can't make 2 it actually return the value without using 1 a semicolon, sorry.

Score: 3

I realize this is an ancient question and 18 has been classed as answered but no-one 17 manages to solve the question in one block, none 16 of them actually give the sum of the even 15 valued terms in one line and in one block 14 and with no semi colons (just noticed that 13 waynes does solve with one line but I thought 12 a one block solution might be nice in response 11 to aroth). here is a solution that does:

``````(1..Float::INFINITY).inject([0,1,0]){|a| if a[0]+a[1] < 4000000 then [a[1],a[0]+a[1],(a[0]+a[1]).even? ? a[2] + (a[0]+a[1]) : a[2]] else break a[2] end }
``````

for 10 a slightly clearer version with one semi 9 colon.

``````(1..Float::INFINITY).inject([0,1,0]){|a| sum=a[0]+a[1]; if sum < 4000000 then [a[1],sum,sum.even? ? a[2] + sum : a[2]] else break a[2] end }
``````

I figure I'll explain it too, three 8 pieces of information get carried forward 7 in the array (as `a` at each iteration) the 6 first fibonacci number, the second fibonacci 5 number and the sum of the even terms. bearing 4 this in mind I think this code is quite 3 clear ruby.

it should be noted that this 2 is basically the same as clems except in 1 one block

Score: 3
``````puts (1..20).inject([0, 1]){|Fibonacci| Fibonacci << Fibonacci.last(2).inject(:+) }
``````

This is the best solution I ever had used 13 to print the Fibonacci series using inject 12 keyword. Explanation: 1) `.inject([0,1])` will hold the 11 default value (0) first value of collection 10 (1) element of the series. 2) At first Fibonacci 9 object will have 0, 1 using `Fibonacci.last(2)` that will be 8 passed through inject 3) `.inject(:+)` will add the 0+1 7 4) This will add 0+1 = 1 and then will 6 be pushed to `Fibonacci` which on next iteration with 5 outer `inject([0,1])` will become `inject(1,2)` here 1 is the value 4 after sum (0+1) and 2 is the next iteration 3 value of collection. and so on till the 2 end of collection

So the series will be 1 like

``````0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
``````
Score: 2

Returns correct values up to `Fib(70)`, beyond that 2 just an approximation. But extremely fast:

``````(((Math.sqrt(5.0) + 1.0) / 2.0)**n / Math.sqrt(5.0) + 0.5).floor
``````

(see 1 https://en.wikipedia.org/wiki/Fibonacci_number#Computation_by_rounding for explanation)

Score: 2

I can think of 4 ways for now to achieve 10 the fibonacci goal!

1. Using a stabby lambda:
``````puts 'Fibonacci Sequence in a Line: ', ->(a=1, b=0) { 10.times.collect { (a, b = b, a + b)[0] } }.call
``````

This evaluates 10 series. But 9 if you want to get the user's number:

``````puts 'Fibonacci Sequence in a Line: ', ->(a=1, b=0) { gets.to_i.times.collect { (a, b = b, a + b)[0] } }.call
``````
1. Using the `tap` method:
``````[0, 1].tap { |a| 10.times { a.push(a[-1] + a[-2]) } }
``````
1. Using the `reduce / inject` method:
``````(1..10).reduce([0, 1]) { |a| a.push(a.last(2).sum) }
``````

or

``````10.times.reduce([0, 1]) { |a| a.push(a.last(2).sum) }
``````
1. Using the `each_with_object` or `map.with_object` method:
``````10.times.each_with_object([0, 1]) { |_, a| a.push(a.last(2).sum) }
``````

Note: If 8 you don't have Ruby 2.4+ you may not have 7 the sum method. In that case, you can add 6 the last two elements with `ary[-2] + ary[-1]` or `ary.last(2).reduce(:+)`.

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

``````[0, 1].tap { |a| until (s = a.last(2).sum) > 4_000_000 do a.push(s) end }.select(&:even?).sum
``````

Or (which is not that 1 great):

``````[0, 1].tap { |a| loop while a.push(a.last(2).sum)[-1] < 4_000_000 }.tap(&:pop).select(&:even?).sum
``````

Outputs: 4613732

Hope this helps!

Score: 1

With the new lazy in ruby 2.0, you can write 1 like this.

``````puts (1..Float::INFINITY).lazy.map{|n| (0..n).inject([1,0]) {|(a,b), _| [b, a+b]}[0] }.take_while{|n| n < 4000000}.select{|x| x % 2 == 0}.reduce(:+)
``````
Score: 1

As a summarizing solution for the answers 4 above, with my humble additions:

``````32.
times.
lazy.
with_object([0, 1]).map { |_, fib| fib[1] = fib[0] + fib[0] = fib[1]; fib[0] }.
take_while(&:>.to_proc.curry(2)[4*10**6]).
select(&:even?).
inject(:+)
``````

I don't 3 really like how currying looks, but didn't 2 want it to look similar to other answers. Alternative 1 `take_while` just for the case:

``````  take_while { |value| value < 4*10**6 }.
``````
Score: 0

Here's a one line ruby solution to Euler 1 prob #2

``````(0..4000000).take_while{|i| (0..i).reduce([1,0]){|(a,b), _| [b, a+b]}[0] <= 4000000 }.map{|i| (0..i).reduce([1,0]){|(a,b), _| [b, a+b]}[0] }.select{|i| i%2 == 0}.reduce(:+)
``````

``````(0..4000000) .
take_while {|i| (0..i).reduce([1,0]){|(a,b), _| [b, a+b]}[0] <= 4000000} .
map {|i| (0..i).reduce([1,0]){|(a,b), _| [b, a+b]}[0]} .
select {|i| i%2 == 0} .
reduce(:+)
``````
Score: 0

`(1..32).inject([0, 1]) { |fib| fib << fib.last(2).inject(:+) }`

0

More Related questions