Sum of even Fibonacci numbers? - ruby

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
a = [1,2]
upto = 4_000_000
while a[-2] + a[-1] < upto
a << a[-2] + a[-1]
end
sum = 0
a.each { |x| sum += x if x.even? }
puts "The result is #{sum}"
How does this work? What is a[-2]? What does that even mean? The negative second index of a or a minus 2? Thanks for the explanation.

This is negative index. a[-1] and a[-2] are the last two elements of the array a.

If you watch closely, you'll see the following sequence:
1 1 2 3 5 8 13 21 34 55 89 144 ...
The formula for mapping the Fibonacci sequence is:
And you only want the sum of the even numbers such as:
1 1 2 3 5 8 13 21 34 55 89 144 ...
So you can map a new formula such as:
And you will obtain the following sequence:
2 8 34 144 ...
Code example (Go):
package main
import "fmt"
func fibonacci() func() int {
first, second := 0, 2
return func() int {
ret := first
first, second = second, first+(4*second)
return ret
}
}
func main() {
sum := 0
f := fibonacci()
for i := 0; sum < 4000000; i++ {
sum += f()
}
fmt.Println(sum)
}
In that case you will not need the if conditionals.
Hope that helped you! Cheers!

def fibonacci(array)
new_fibs = []
new_fibs << array[0]
new_fibs << array[1]
sum = 0
i = 0
while new_fibs.last < 4_000_000
sum = new_fibs[i] + new_fibs[i+1]
new_fibs << sum
i += 1
end
total_even = 0
new_fibs.each do |fibs|
if fibs%2 == 0
total_even = total_even + fibs
end
end
p total_even
end
fibonacci([1,2])
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

Related

Ruby program to print first n Fibonacci Seqeunce

Newbie here! Trying to implement a program to print the first 20 Fibonacci numbers in Ruby. I've managed to create a program which generates the nth number, but I want to produce all from 0 through to 20.
Is there a simple way to do this or do I need to rewrite the whole program?
CURRENT CODE
def fib(n)
if n < 1
return 0
elsif n == 1
return 1
else fib(n-2) + fib(n-1)
end
end
puts fib(20)
CURRENT OUTPUT EXAMPLE
6765
DESIRED OUTCOME
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
At the moment you only print the last value returned by your method (fib(20)) but not the result of all intermediate steps.
An easy way would be to cache all intermediate results in a hash data structure. This would also improve performance for big n because you do not need to recalculate many values over and over again.
Then you can just print out all results from 0 to n:
def cached_fib(n)
#cache ||= Hash.new do |cache, n|
#cache[n] = n < 2 ? n : cache[n-1] + cache[n-2]
end
#cache[n]
end
def fib(n)
0.upto(n) { |i| puts cached_fib(i) }
end
fib(20)
#=> 0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
Printing each value is easier with a button-up approach where you start at 0 and 1 and calculate each following value based on its predecessors, e.g.:
i, j = 0, 1
puts i
puts j
21.times do
k = i + j
puts k
i, j = j, k
end
You could turn the above into an Enumerator:
fib = Enumerator.new do |y|
i, j = 0, 1
y << i
y << j
loop do
k = i + j
y << k
i, j = j, k
end
end
Which will generate the sequence:
fib.take(21)
#=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,
# 233, 377, 610, 987, 1597, 2584, 4181, 6765]

Partial Fibonacci Sum, how to improve performance?

I need to improve the performance of this algorithm. I believe the answer lies in the application of the pisano period.
This algorithm must return the last digit of the sum of fib numbers from f(m) to f(n).
Here is what I have so far:
def fib(n)
a = []
a << 0 << 1
(n+1).times do |i|
a << a[-1] + a[-2]
end
a[n]
end
def fib_partial_sum(m, n)
if n == m
fib(m) % 10
else
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
The last digit of any fib num repeats every 60 numbers. Therefore, we can do this, n, m = n % 60, m % 60. An improvement, but not quite there yet, fails on input 567717153638 567717153638):
def fib(n)
a = []
a << 0 << 1
(n+1).times do |i|
a << a[-1] + a[-2]
end
a[n]
end
def fib_partial_sum(m, n)
if n == m
fib(m)
else
m = m % 60
n = n % 60
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
Here is a nice solution to the problem, it passes all time and memory constraints.
This way you never have to calculate a fib num greater that f(60). It can handle very large inputs efficiently.
def fib(n)
a, b = 0, 1
(n-1).times do
a, b = b, (a + b) % 10
end
b
end
def fib_partial_sum(m, n)
if n == m
fib(m % 60)
else
m = m % 60
n = n % 60
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
(Max time used: 0.05/5.00, max memory used: 8699904/536870912.)
The following requires only a single pass of the numbers between zero and at most [n,m+60].min, where m..n is the range of interest, and has a minimal memory requirement. It makes use of #nloveladyallen's observation that the last digit of Fibonacci numbers has a periodicity of 60.
Code
def fib_last(m,n)
n -= 60*((n-m)/60)
fib_sum(m,n) % 10
end
def fib_sum(m,n)
return nil if m < 0 || m > n
return n if n < 2
next_to_last, last = fib(m-1)
(m..n).reduce(0) do |tot,_|
current = next_to_last + last
next_to_last = last
last = current
tot + current
end
end
def fib(m)
next_to_last, last = -1, 1
0.upto(m).each do |n|
current = next_to_last + last
next_to_last, last = last, current
end
[next_to_last, last]
end
Example
m, n = 6, 12
(n+1).times { |i| puts "#{i}: #{fib(i)}" }
0: [0, 0]
1: [0, 1]
2: [1, 1]
3: [1, 2]
4: [2, 3]
5: [3, 5]
6: [5, 8]
7: [8, 13]
8: [13, 21]
9: [21, 34]
10: [34, 55]
11: [55, 89]
12: [89, 144]
fib_last(6,12) #=> 4 (fib_sum(6,12) #=> 8 + 13 + 21 + 34 + 55 + 89 + 144 = 364)
fib_last(1,2) #=> 2 (fib_sum(1,2) #=> 1 + 1 = 2)
fib_last(1,3) #=> 4 (fib_sum(1,3) #=> 1 + 1 + 2 = 4)
fib_last(1,4) #=> 7 (fib_sum(1,4) #=> 1 + 1 + 2 + 3 = 7)
fib_last(2,3) #=> 3 (fib_sum(2,3) #=> 1 + 2 = 3)

Generating Ascending Sequence 2^p*3^q

I was interested in implementing a specific Shellsort method I read about that had the same time complexity as a bitonic sort. However, it requires the gap sequence to be the sequence of numbers [1, N-1] that satisfy the expression 2^p*3^q for any integers p and q. In layman's terms, all the numbers in that range that are only divisible by 2 and 3 an integer amount of times. Is there a relatively efficient method for generating this sequence?
Numbers of that form are called 3-smooth. Dijkstra studied the closely related problem of generating 5-smooth or regular numbers, proposing an algorithm that generates the sequence S of 5-smooth numbers by starting S with 1 and then doing a sorted merge of the sequences 2S, 3S, and 5S. Here's a rendering of this idea in Python for 3-smooth numbers, as an infinite generator.
def threesmooth():
S = [1]
i2 = 0 # current index in 2S
i3 = 0 # current index in 3S
while True:
yield S[-1]
n2 = 2 * S[i2]
n3 = 3 * S[i3]
S.append(min(n2, n3))
i2 += n2 <= n3
i3 += n2 >= n3
Simplest I can think of is to run a nested loop over p and q and then sort the result. In Python:
N=100
products_of_powers_of_2and3 = []
power_of_2 = 1
while power_of_2 < N:
product_of_powers_of_2and3 = power_of_2
while product_of_powers_of_2and3 < N:
products_of_powers_of_2and3.append(product_of_powers_of_2and3)
product_of_powers_of_2and3 *= 3
power_of_2 *= 2
products_of_powers_of_2and3.sort()
print products_of_powers_of_2and3
result
[1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96]
(before sorting the products_of_powers_of_2and3 is
[1, 3, 9, 27, 81, 2, 6, 18, 54, 4, 12, 36, 8, 24, 72, 16, 48, 32, 96, 64]
)
Given the size of products_of_powers_of_2and3 is of the order of log2N*log3N the list doesn't grow very fast and sorting it doesn't seem particularly inefficient. E.g. even for N = 1 million, the list is very short, 142 items, so you don't need to worry.
You can do it very easy in JavaScript
arr = [];
n = 20;
function generateSeries() {
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
arr.push(Math.pow(2, i) * Math.pow(3, j))
}
}
sort();
}
function sort() {
arr.sort((a, b) => {
if (a < b) {return -1;}
if (a > b) {return 1;}
return 0;
});
}
function solution(N) {
arr = [];
if (N >= 0 && N <= 200 ) {
generateSeries();
console.log("arr >>>>>", arr);
console.log("result >>>>>", arr[N]);
return arr[N];
}
}
N = 200
res =[]
a,b = 2,3
for i in range(N):
for j in range(N):
temp1=a**i
temp2=b**j
temp=temp1*temp2
if temp<=200:
res.append(temp)
res = sorted(res)
print(res)

Why does these two injects give the same output in ruby?

Why is the output the same?
First inject:
puts (3...10).inject(0) { |sum, x| (x % 3 == 0 || x % 5 == 0) ? sum + x : sum }
# => 23
Second inject:
puts (3...10).inject { |sum, x| (x % 3 == 0 || x % 5 == 0) ? sum + x : sum }
# => 23
# Why not 26?
I thought if there is no argument passed to it, inject uses the first element of the collection as initial value.
So the second inject should return the same value as this one:
puts (3...10).inject(3) { |sum, x| (x % 3 == 0 || x % 5 == 0) ? sum + x : sum }
# => 26
Why does these two injects give the same output in ruby?
... Because they're supposed to. They only differ by the addition of a 0.
I thought if there is no argument passed to it, inject uses the first element of the collection as initial value.
It does. But it doesn't duplicate it.
Your first example receives these numbers:
0, 3, 4, 5, 6, 7, 8, 9
Your second example receives these numbers:
3, 4, 5, 6, ...
Adding 0 to the beginning doesn't affect the result, they're both 23, not 26 as you claim.
Your 3rd example returns 26 because it receives these numbers:
3, 3, 4, 5, 6, ...
#inject() with an argument:
result = (3...10).inject(0) do |sum, x|
puts "#{sum} <-- #{x}: sum = #{sum+x}"
sum + x
end
--output:--
0 <-- 3: sum = 3
3 <-- 4: sum = 7
7 <-- 5: sum = 12
12 <-- 6: sum = 18
18 <-- 7: sum = 25
25 <-- 8: sum = 33
33 <-- 9: sum = 42
...
#inject without an argument:
result = (3...10).inject() do |sum, x|
puts "#{sum} <-- #{x}: sum = #{sum+x}"
sum + x
end
--output:--
3 <-- 4: sum = 7
7 <-- 5: sum = 12
12 <-- 6: sum = 18
18 <-- 7: sum = 25
25 <-- 8: sum = 33
33 <-- 9: sum = 42
I always thought it takes the first element of the collection as
initial value and still performs the first iteration
The first iteration uses arr[0] as the sum and arr[1] as the first x. When you don't provide an argument for inject(), it's equivalent to doing this:
data = (3...10).to_a
initial_sum = data.shift
data.inject(initial_sum) do |sum, x|
puts "#{sum} <-- #{x}: sum = #{sum+x}"
sum + x
end
--output:--
3 <-- 4: sum = 7
7 <-- 5: sum = 12
12 <-- 6: sum = 18
18 <-- 7: sum = 25
25 <-- 8: sum = 33
33 <-- 9: sum = 42

Generating integer partition by its number

I'm trying to generate decent partition of given integer number N numbered K in lexicographical order, e.g. for N = 5, K = 3 we got:
5 = 1 + 1 + 1 + 1 + 1
5 = 1 + 1 + 1 + 2
5 = 1 + 1 + 3
5 = 1 + 2 + 2
5 = 1 + 4
5 = 2 + 3
5 = 5
And the third one is 1 + 1 + 3.
How can I generate this without generating every partition(in C language, but most of all I need algorithm)?
Going to find maximal number in partition(assuming we can find number of partitions d[i][j], where i is number and j is maximal integer in its partition), then decrease the original number and number we are looking for. So yes, I'm trying to use dynamic programming. Still working on code.
This doesn't work at all:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *F1, *F2;
main()
{
long long i, j, p, n, k, l, m[102][102];
short c[102];
F1 = fopen("num2part.in", "r");
F2 = fopen ("num2part.out", "w");
n = 0;
fscanf (F1, "%lld %lld", &n, &k);
p = 0;
m[0][0] = 1;
for ( i = 0; i <= n; i++)
{
for (j = 1; j <= i; j++)
{
m[i][j] = m[i - j][j] + m[i][j - 1];
}
for (j = i + 1; j <= n; j++)
{
m[i][j] = m[i][i];
}
}
l = n;
p = n;
j = n;
while (k > 0)
{
while ( k < m[l][j])
{
if (j == 0)
{
while (l > 0)
{
c[p] = 1;
p--;
l--;
}
break;
}
j--;
}
k -=m[l][j];
c[p] = j + 1;
p--;
l -= c[p + 1];
}
//printing answer here, answer is contained in array from c[p] to c[n]
}
Here is some example Python code that generates the partitions:
cache = {}
def p3(n,val=1):
"""Returns number of ascending partitions of n if all values are >= val"""
if n==0:
return 1 # No choice in partitioning
key = n,val
if key in cache:
return cache[key]
# Choose next value x
r = sum(p3(n-x,x) for x in xrange(val,n+1))
cache[key]=r
return r
def ascending_partition(n,k):
"""Generate the k lexicographically ordered partition of n into integer parts"""
P = []
val = 1 # All values must be greater than this
while n:
# Choose the next number
for x in xrange(val,n+1):
count = p3(n-x,x)
if k >= count:
# Keep trying to find the correct digit
k -= count
elif count: # Check that there are some valid positions with this digit
# This must be the correct digit for this location
P.append(x)
n -= x
val = x
break
return P
n=5
for k in range(p3(n)):
print k,ascending_partition(n,k)
It prints:
0 [1, 1, 1, 1, 1]
1 [1, 1, 1, 2]
2 [1, 1, 3]
3 [1, 2, 2]
4 [1, 4]
5 [2, 3]
6 [5]
This can be used to generate an arbitrary partition without generating all the intermediate ones. For example, there are 9253082936723602 partitions of 300.
print ascending_partition(300,10**15)
prints
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 7, 8, 8, 11, 12, 13, 14, 14, 17, 17, 48, 52]
def _yieldParts(num,lt):
''' It generate a comination set'''
if not num:
yield ()
for i in range(min(num,lt),0,-1):
for parts in _yieldParts(num-i,i):
yield (i,)+parts
def patition(number,kSum,maxIntInTupple):
''' It generates a comination set with sum of kSum is equal to number
maxIntInTupple is for maximum integer can be in tupple'''
for p in _yieldParts(number,maxIntInTupple):
if(len(p) <=kSum):
if(len(p)<kSum):
while len(p) < kSum:
p+=(0,)
print p
patition(40,8,40)
Output:
-------
(40,0,0,0,0,0,0,0)
(39,1,0,0,0,0,0,0)
.
.
.
.

Resources