Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm trying to learn the basics of C++ by going through some Project Euler problems. I've made it to...#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, ...
Find the sum of all the even-valued
terms in the sequence which do not
exceed four million.
My logic:
0, 1, 1, 2, 3, 5
x y z
x y z
x y z
x y z
The above is looping through this:
x + y = z
x = y
y = z
My code:
#include <iostream.h>
using namespace std;
int main()
{
int x = 0;
int y = 1;
int z;
int sum;
for(y = 1; y <= 4000000; y++) {
z = x + y;
x = y;
y = z;
if(y % 2 == 0) {
sum += y;
}
}
cout << sum;
cin.get();
}
That outputs 4613788
The correct answer, though, is 4613732.
You're using y as both the loop variable, and the second term in the sequence.
What you mean to do is:
int x = 0;
int y = 1;
int z;
int sum = 0;
do {
z = x + y;
x = y;
y = z;
if (y % 2 == 0) sum += y;
} while (y <= 4000000);
Noting that you should probably initialize sum as well.
For a speed improvement, note that the sequence is Even-Odd-Odd (repeats), Even-Odd-Odd.
You don't need to test each number to know if it is even or odd. Just add every third number.
You're not initialising sum to zero.
The for loop code block should be something like
while(y <= 4000000) {
z = x + y;
x = y;
y = z;
if(y % 2 == 0) {
sum += y;
}
}
Basically, you should not increment y.
Here is how we can do in minimum number of loops. If we write Fibonacci series in terms of first two numbers, it is:
a, b, (a+b), (a+2b), (2a+3b), (3a+5b), (5a+8b), (8a+13b), (13a+21b), (21a+34b), (34a+55b)....
In above series a is 1 and b is 2, highlighted numbers are even numbers. In Fibonacci series every third number is even number, sequence is EVEN-ODD-ODD-EVEN-. So if we write even number is this series, it is:
b, (2a+3b), (8a+13b), (34a+55b), (144a+233b)...
If we observe pattern in this series, coefficient_of_next_a is 4*(coefficient_of_current_a)+(coefficient_of_previous_a).
And coefficient_of_next_b is (coefficient_of_current_a)+(coefficient_of_current_b)+(coefficient_of_next_a).
Python Code:
# Start sum with first event number
sum = 2
# Values of first two Fibonacci numbers
a = 1
b = 2
# Previous coefficient of a
prev_coef_a = 0
# Current coefficient of a and b
coef_a = 2
coef_b = 3
while ((coef_a*a)+(coef_b*b)) <= 4000000:
print(((coef_a*a)+(coef_b*b)))
sum += ((coef_a*a)+(coef_b*b))
# Coefficient of a for next number
next_coef_a = (coef_a*4)+prev_coef_a
prev_coef_a = coef_a
# Coefficient of b for next number
coef_b = coef_a+coef_b+next_coef_a
coef_a = next_coef_a
print('Sum: {}'.format(sum))
Output is:
8
34
144
610
2584
10946
46368
196418
832040
3524578
Sum: 4613732
Here is a way to solve this problem in O(log(N))-time vs. the slower O(N) implementation (O(log(N)) comes from the need to use the pow() function).
First, you need to be able to compute the N-th Fibonacci number in O(log(N)) time:
double Fib(double N)
{
double Fn = (pow(PHI, N) - pow(PSI, N)) / sqrt(5);
return floor(Fn);
}
where PHI = 1.6180339... and PSI = -0.61803398... (check out wiki for more info)
Second, you will need to calculate the closest index to your target limit (in problem 2's case this would be 4,000,000):
double nFib(double F)
{
double nFib = log((double)F * sqrt(5) + 0.5) / log(PHI);
return floor(nFib);
}
Third, you will use the B&Q identity #25 (more info here) for calculating the sum of the even Fibonacci numbers:
double bqIdentity25(double N)
{
return (Fib(3*floor(N) + 2) - 1) / 2;
}
Finally, compute the sum:
double limit = 4000000;
double nearestIndex = nFib(limit);
double sum = bqIdentity25(nearestIndex / 3);
we only need every third element to compute the sum of the even Fibonacci numbers.
Hope this helps!
Will
//fibonacci sequence
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<unsigned long int> list;
list.clear();
list.push_back(1);
list.push_back(2);
cout<<"1\n2\n";
unsigned long int last;
unsigned long int prev;
do{
last=list.at(list.size()-1);
prev=list.at(list.size()-2);
list.push_back(last+prev);
cout << list.at(list.size()-1)<<'\n';
}while(last<4000000);
unsigned long int sum=0;
for(int a=0;a<list.size();a++)
{
if(list.at(a)%2==0)
{
sum+=list.at(a);
}
}
cout <<'\n'<<sum<<'\n';
return 0;
}
perl -e '$a,$b=(0,1);while($a<4*10**6){$a%2==0and$sum+=$a;$a+=$b;$c=$a;$a=$b;$b=$c;}print"$sum\n"'
I recently began studying the arcane art of Perl...(LOVE IT!)
but I will explain it... we need three variables that we will move our 2 values that we need in order to find the next step in the sequence(which will be assigned to the 3rd var like this $c=$a;$a=$b;$b=$c;). $a and $b are declared upfront because we know the fibo starts with them($a,$b=(0,1)). From there we get a a while loop rolling as long as our variable that we use in our boologic is less than 4mil(while($a<4*10**6)). Every iteration we check for even numbers($a%2==0) with modulus and plus-equals these to our $sum variable($sum+=$a). After shuffling the variables(as mentioned earlier) it's just 'print and done'.
I know you wanted to do this in C/C++ (perl is written in C) but I was just messing around with the euler problems in Perl and thought this might provide insight.
if it doesn't help at all(aside from not being the right language) please tell me how to improve my answer so I can provide better answers in the future. Most importantly, have a nice day!
Golf anyone?
It shows each Fibonacci Sequence Number and selects even ones,
at the end gives sum of the even ones.
#include <stdio.h>
#include <math.h>
#include <time.h>
//project euler
//problem# 2
int main()
{
long int a = 0;
long int b = 1;
long int sum = 0;
long int f = 0;
long int t = 1;
long int d = 1;
while (f <= 4000000){
f = a + b;
printf(" %2d. number is %7d",d,f);
d++;
a = b;
b = f;
if (f % 2 == 0){
sum += f;
printf("\t\t%2d. target is %7d",t,f);
t++;
}
printf("\n\n");
printf("--------------------------------------------------------------------------------");
}
printf("\n\n\t\t\t\t\tSum of targets is %d\n\n\n", sum);
printf("--------------------------------------------------------------------------------\n");
printf("Press any key to continue...\n");
getchar();
}
Trying to add little help to the problem.Following program shows all even fibonacci series numbers for a given length of series which is input by user.
#include<iostream.h>
#include<conio.h>
class fibonacci
{
int input;
public:
void series();
};
void fibonacci::series()
{
cout<<"enter the value";
cin>>input;
int initial=0;
int initial1=1;
for(int loop=0;loop<input;loop++)
{
int initial2;
initial2=initial1+initial;
if(initial2%2==0)
{cout<<initial2<<"\t";}
initial=initial1;
initial1=initial2;
}
}
void main()
{
fibonacci a;
a.series();
getch();
}
Here is how to do it in Swift:
/** Calculate the next even fibonacci number within a limit.
Methodology:
1) Fibonacci numbers are either odd (o) or even (e) as follows:
o, e, o, o, e, o, o, e, o, o, e, ... because of the arithmetic
rule:
Odd + Odd = Even
Even + Even = Even
Odd + Even = Odd
2) By do two rounds of fibonacci, we can get from one "e" to the
next "e". We don't need to bother checking its even.
3) To avoid re-computing past results, we ask for the past
running total to be supplied, and the past pair of fibonacci
numbers before doing our two rounds of fibonacci
4) We assume the passed in pair of fibonacci numbers don't exceed
are supplied limit, and on the next even fibonacci we can just test
for exceeding the limit there only.
5) Fibonacci numbers grow very fast (nearly doubling each time). Since
the next even is found after two iterations, it means we have exponential
growth for the next fibonacci number. For limit L, we'll find the sum
after O(log(L)) time.
#param runningTotal Total of even fibonacci numbers seen so far
#param upperLimit Limit number not to exceed the next even fibonacci
#param n0 First of an adjacent pair of fibonacci numbers with
n0 < upperLimit
#param n1 Next fibonacci number after n1 with n1 < upperLimit
#returns (updatedTotal,n3,n4) where updatedTotal is the supplied runningTotal
plus the next even fibonacci number not exceeding the supplied
upperLimit, n3 and n4 are the next pair of fibonacci numbers to be
supplied for the next call to this method
*/
func sumNextEvenFibonacci(runningTotal:Int, upperLimit:Int, n0:Int, n1:Int) -> (Int, Int, Int)
{
let n2 = n0 + n1
let n3 = n2 + n1
let n4 = n3 + n2
if (n4 < upperLimit)
{
return (runningTotal + n4, n3, n4)
}
else
{
return (runningTotal, n3, n4)
}
}
func eulerProblem_02()
{
println("Problem 2\n\nEach 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:\n 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... \n\nBy considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.\n")
var n0 = 1, n1 = 2, n2 = 0, runningTotal = 2
do
{
(runningTotal, n0, n1) = sumNextEvenFibonacci(runningTotal, 4_000_000, n0, n1)
} while (n1 < 4_000_000)
println("The answer is \(runningTotal).\n")
}
eulerProblem_02()
The program outputs:
Problem 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.
The answer is 4613732.
A solution using Kotlin, I'm using this problems to practice my math and learn this new language for me:
import java.math.BigInteger
/**
*
* https://projecteuler.net/problem=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.
*
*/
class Problem2 {
var maxValue: Int = 4000000
// Looking for this fibonacci value
var fibonacci = 32
var fibonacciValues = hashMapOf<Int, BigInteger>(0 to BigInteger.ONE, 1 to BigInteger.ONE);
fun solution(): BigInteger {
var solution: BigInteger = BigInteger.ZERO
calculateFibonacci(fibonacci)
fibonacciValues.filter {
it.value < BigInteger.valueOf(maxValue.toLong()) &&
it.value.mod(BigInteger.ONE.add(BigInteger.ONE)).equals(BigInteger.ZERO)
}.forEach {
//println("Key: ${it.key} and ${it.value} and mv $maxValue")
solution = solution.add(it.value)
}
return solution
}
private fun calculateFibonacci(n: Int): BigInteger? {
if ( fibonacciValues.contains(n)) {
return fibonacciValues.get(n)
} else {
val f = calculateFibonacci(n - 2)!!.add(calculateFibonacci(n - 1))
fibonacciValues.put(n, f)
return f
}
}
}
It's a little verbose because, I'm adding testability, if you want to see the Unit Test, here it is:
https://github.com/moxi/project-euler-solutions/blob/master/code/src/test/kotlin/org/rcgonzalezf/onetoten/Problem2Test.kt
Every 3rd number is even, so sum of even numbers is (sum of n fib numbers)/2.
But, some of n fib. numbers = (n+2)'s term - 2nd term(1).
You can get (n+2)th term from benet's formula
In javascript you can solve it like this:
function add(a, b) {
// body...
return a + b;
}
function fabonacci(limit) {
var i = 2; //parseInt(limit);
var fabonacci = [0, 1];
var evenFab = [];
var valToPush = 0;
var result = [];
while (valToPush < 4000000) {
valToPush = fabonacci[fabonacci.length - 2] + fabonacci[fabonacci.length - 1]
i++;
if ((valToPush % 2) == 0) {
evenFab.push(valToPush);
}
if (valToPush > 4000000 || i > limit) {
break;
}
fabonacci.push(valToPush);
}
result['sequence'] = fabonacci;
result['sumOfEven'] = evenFab;
return result;
}
var result = fabonacci(10);
console.log("Fabonacci sequence:" + result['sequence']);
console.log("Sum of Even Number:" + (result['sumOfEven']).reduce(add, 0));`
a = 0
b = 1
c =0
sum = 0
d = 0
for s in range(4000000):
while(d<4000000):
d = a+b
if d%2 == 0:
sum += d
print(d)
a = b
b = d
print
print
print("the sum is:"+str(sum))
You have to use long data type instead of int .
My Solution :
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long sum = 0;
long f = 1, s = 2;
for(f, s; f<4000000 || s < 4000000; )
{
//cout << f << " " << s << endl;
if( f%2 == 0 )
sum += f;
if( s%2 == 0)
sum+= s;
f += s;
s+=f;
}
cout << sum <<endl;
return 0;
}
Related
I should implement this summation in C ++. I have tried with this code, but with very high numbers up to 10 ^ 12 it takes too long.
The summation is:
For any positive integer k, let d(k) denote the number of positive divisors of k (including 1 and k itself).
For example, for the number 4: 1 has 1 divisor, 2 has two divisors, 3 has two divisors, and 4 has three divisors. So the result would be 8.
This is my code:
#include <iostream>
#include <algorithm>
using namespace std;
int findDivisors(long long n)
{
int c=0;
for(int j=1;j*j<=n;j++)
{
if(n%j==0)
{
c++;
if(j!=(n/j))
{
c++;
}
}
}
return c;
}
long long compute(long long n)
{
long long sum=0;
for(int i=1; i<=n; i++)
{
sum += (findDivisors(i));
}
return sum;
}
int main()
{
int n, divisors;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
cin >> n;
cout << compute(n);
}
I think it's not just a simple optimization problem, but maybe I should change the algorithm entirely.
Would anyone have any ideas to speed it up? Thank you.
largest_prime_is_463035818's answer shows an O(N) solution, but the OP is trying to solve this problem
with very high numbers up to 1012.
The following is an O(N1/2) algorithm, based on some observations about the sum
n/1 + n/2 + n/3 + ... + n/n
In particular, we can count the number of terms with a specific value.
Consider all the terms n/k where k > n/2. There are n/2 of those and all are equal to 1 (integer division), so that their sum is n/2.
Similar considerations hold for the other dividends, so that we can write the following function
long long count_divisors(long long n)
{
auto sum{ n };
for (auto i{ 1ll }, k_old{ n }, k{ n }; i < k ; ++i, k_old = k)
{ // ^^^^^ it goes up to sqrt(n)
k = n / (i + 1);
sum += (k_old - k) * i;
if (i == k)
break;
sum += k;
}
return sum;
}
Here it is tested against the O(N) algorithm, the only difference in the results beeing the corner cases n = 0 and n = 1.
Edit
Thanks again to largest_prime_is_463035818, who linked the Wikipedia page about the divisor summatory function, where both an O(N) and an O(sqrt(N)) algorithm are mentioned.
An implementation of the latter may look like this
auto divisor_summatory(long long n)
{
auto sum{ 0ll };
auto k{ 1ll };
for ( ; k <= n / k; ++k )
{
sum += n / k;
}
--k;
return 2 * sum - k * k;
}
They also add this statement:
Finding a closed form for this summed expression seems to be beyond the techniques available, but it is possible to give approximations. The leading behavior of the series is given by
D(x) = xlogx + x(2γ - 1) + Δ(x)
where γ is the Euler–Mascheroni constant, and the error term is Δ(x) = O(sqrt(x)).
I used your brute force approach as reference to have test cases. The ones I used are
compute(12) == 35
cpmpute(100) == 482
Don't get confused by computing factorizations. There are some tricks one can play when factorizing numbers, but you actually don't need any of that. The solution is a plain simple O(N) loop:
#include <iostream>
#include <limits>
long long compute(long long n){
long long sum = n+1;
for (long long i=2; i < n ; ++i){
sum += n/i;
}
return sum;
}
int main()
{
std::cout << compute(12) << "\n";
std::cout << compute(100) << "\n";
}
Output:
35
482
Why does this work?
The key is in Marc Glisse's comment:
As often with this kind of problem, this sum actually counts pairs x,
y where x divides y, and the sum is arranged to count first all x
corresponding to a fixed y, but nothing says you have to keep it that
way.
I could stop here, because the comment already explains it all. Though, if it didn't click yet...
The trick is to realize that it is much simpler to count divisors of all numbers up to n rather than n-times counting divisors of individual numbers and take the sum.
You don't need to care about factorizations of eg 123123123 or 52323423 to count all divisors up to 10000000000. All you need is a change of perspective. Instead of trying to factorize numbers, consider the divisors. How often does the divisor 1 appear up to n? Simple: n-times. How often does the divisor 2 appear? Still simple: n/2 times, because every second number is divisible by 2. Divisor 3? Every 3rd number is divisible by 3. I hope you can see the pattern already.
You could even reduce the loop to only loop till n/2, because bigger numbers obviously appear only once as divisor. Though I didn't bother to go further, because the biggest change is from your O(N * sqrt(N)) to O(N).
Let's start off with some math and reduce the O(n * sq(n)) factorization to O(n * log(log(n))) and for counting the sum of divisors the overall complexity is O(n * log(log(n)) + n * n^(1/3)).
For instance:
In Codeforces himanshujaju explains how we can optimize the solution of finding divisors of a number.
I am simplifying it a little bit.
Let, n as the product of three numbers p, q, and r.
so assume p * q * r = n, where p <= q <= r.
The maximum value of p = n^(1/3).
Now we can loop over all prime numbers in a range [2, n^(1/3)]
and try to reduce the time complexity of prime factorization.
We will split our number n into two numbers x and y => x * y = n.
And x contains prime factors up to n^(1/3) and y deals with higher prime factors greater than n^(1/3).
Thus gcd(x, y) = 1.
Now define F(n) as the number of prime factors of n.
From multiplicative rules, we can say that
F(x * y) = F(x) * F(y), if gcd(x, y) = 1.
For finding F(n) => F(x * y) = F(x) * F(y)
So first find F(x) then F(y) will F(n/x)
And there will 3 cases to cover for y:
1. y is a prime number: F(y) = 2.
2. y is the square of a prime number: F(y) = 3.
3. y is a product of two distinct prime numbers: F(y) = 4.
So once we are done with finding F(x) and F(y), we are also done with finding F(x * y) or F(n).
In Cp-Algorithm there is also a nice explanation of how to count the number of divisors on a number. And also in GeeksForGeeks a nice coding example of how to count the number of divisors of a number in an efficient way. One can check the articles and can generate a nice solution to this problem.
C++ implementation
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 11;
bool prime[maxn];
bool primesquare[maxn];
int table[maxn]; // for storing primes
void SieveOfEratosthenes()
{
for(int i = 2; i < maxn; i++){
prime[i] = true;
}
for(int i = 0; i < maxn; i++){
primesquare[i] = false;
}
// 1 is not a prime number
prime[1] = false;
for(int p = 2; p * p < maxn; p++){
// If prime[p] is not changed, then
// it is a prime
if(prime[p] == true){
// Update all multiples of p
for(int i = p * 2; i < maxn; i += p){
prime[i] = false;
}
}
}
int j = 0;
for(int p = 2; p < maxn; p++) {
if (prime[p]) {
// Storing primes in an array
table[j] = p;
// Update value in primesquare[p * p],
// if p is prime.
if(p < maxn / p) primesquare[p * p] = true;
j++;
}
}
}
// Function to count divisors
int countDivisors(int n)
{
// If number is 1, then it will have only 1
// as a factor. So, total factors will be 1.
if (n == 1)
return 1;
// ans will contain total number of distinct
// divisors
int ans = 1;
// Loop for counting factors of n
for(int i = 0;; i++){
// table[i] is not less than cube root n
if(table[i] * table[i] * table[i] > n)
break;
// Calculating power of table[i] in n.
int cnt = 1; // cnt is power of prime table[i] in n.
while (n % table[i] == 0){ // if table[i] is a factor of n
n = n / table[i];
cnt = cnt + 1; // incrementing power
}
// Calculating the number of divisors
// If n = a^p * b^q then total divisors of n
// are (p+1)*(q+1)
ans = ans * cnt;
}
// if table[i] is greater than cube root of n
// First case
if (prime[n])
ans = ans * 2;
// Second case
else if (primesquare[n])
ans = ans * 3;
// Third case
else if (n != 1)
ans = ans * 4;
return ans; // Total divisors
}
int main()
{
SieveOfEratosthenes();
int sum = 0;
int n = 5;
for(int i = 1; i <= n; i++){
sum += countDivisors(i);
}
cout << sum << endl;
return 0;
}
Output
n = 4 => 8
n = 5 => 10
Complexity
Time complexity: O(n * log(log(n)) + n * n^(1/3))
Space complexity: O(n)
Thanks, #largest_prime_is_463035818 for pointing out my mistake.
I'm trying to solve the 2nd problem on Project Euler where I have to print the sum of all even Fibonacci numbers under 4 million. I'm using the following code but the program is not returning any value. When I replace 4000000 by something small like 10, I get the sum. Does that mean my program is taking too long? What am I doing wrong?
#include <iostream>
using namespace std;
int fibonacci(int i) {
if (i == 2)
return 2;
else if (i == 1)
return 1;
else return fibonacci(i - 1) + fibonacci(i - 2);
}
int main() {
int currentTerm, sum = 0;
for (int i = 1; i <= 10; i++) {
currentTerm = fibonacci(i);
if (currentTerm % 2 == 0)
sum += currentTerm;
}
cout << sum;
return 0;
}
Problem 2 of project Euler asks (emphasis mine)
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
Doing
for (int i = 1; i <= 4000000; i++)
{
currentTerm = fibonacci(i);
// ...
}
You are trying to calculate up to the 4,000,000th Fibonacci number, which is a very big beast, while you should stop around the 33th instead.
The other answers already pointed out the inefficiency of the recursive approach, but let me add some numbers to the discussion, using this slightly modified version of your program
#include <iostream>
#include <iomanip>
int k = 0;
// From https://oeis.org/A000045 The fibonacci numbers are defined by the
// recurrence relation F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
// In the project Euler question the sequence starts with 1, 2, 3, 5, ...
// So in the following I'll consider F(1) = 1 and F(2) = 2 as The OP does.
long long fibonacci(long long i)
{
++k;
if (i > 2)
return fibonacci(i - 1) + fibonacci(i - 2);
else
return i;
}
int main()
{
using std::cout;
using std::setw;
const long limit = 4'000'000;
long sum = 0;
cout << " i F(i) sum calls\n"
"-----------------------------------\n";
for (int i = 1; ; ++i)
{
long long F_i = fibonacci(i);
if ( F_i > limit ) // <-- corrected end condition
break;
if (F_i % 2 == 0)
{
sum += F_i;
cout << setw(3) << i << setw(10) << F_i
<< setw(10) << sum << setw(11) << k << '\n';
}
}
cout << "\nThe sum of all even Fibonacci numbers less then "
<< limit << " is " << sum << '\n';
return 0;
}
Once executed (live here), you can notice that the recursive function has been called more than 10,000,000 times, to calculate up to the 33th Fibonacci number.
That's simply not the right way. Memoization could help, here there's a quick benchmark comparing the recursive functions with a toy implementation of the memoization technique, which is represented by the histogram that you can't see. Because it's 300,000 times shorter than the others.
Still, that's not the "correct" or "natural" way to deal with this problem. As noted in the other answers you could simply calculate each number in sequence, given the previous ones. Enthus3d also noted the pattern in the sequence: odd, odd, even, odd, odd, even, ...
We can go even further and directly calculate only the even terms:
#include <iostream>
int main()
{
const long limit = 4'000'000;
// In the linked question the sequence starts as 1, 2, 3, 5, 8, ...
long long F_0 = 2, F_3 = 8, sum = F_0 + F_3;
for (;;)
{
// F(n+2) = F(n+1) + F(n)
// F(n+3) = F(n+2) + F(n+1) = F(n+1) + F(n) + F(n+1) = 2F(n+1) + F(n)
// F(n+6) = F(n+5) + F(n+4) = F(n+4) + F(n+3) + F(n+3) + F(n+2)
// = 2F(n+3) + F(n+4) + F(n+2) = 3F(n+3) + 2F(n+2)
// = 3F(n+3) + 2F(n+1) + 2F(n) = 3F(n+3) + F(n+3) - F(n) + 2F(n)
long long F_6 = 4 * F_3 + F_0;
if ( F_6 > limit )
break;
sum += F_6;
F_0 = F_3;
F_3 = F_6;
}
std::cout << sum << '\n'; // --> 4613732
return 0;
}
Live here.
If you need multiple Fibonacci numbers, and especially if you need all of them, do not use the recursive approach, use iteration instead:
var prev=0;
var curr=1;
var sum=0;
while(curr<4000000){
if(curr%2==0)
sum+=curr;
var temp=prev;
prev=curr;
curr+=temp;
}
console.log(sum);
The snippet is JavaScript (so it can run here), but if you make var-s to int-s, it will be C-ish enough.
But the actual problem was the loop: you do not need to calculate the first
n (4000000) Fibonacci numbers (which would lead to various overflows), but the Fibonacci numbers which are smaller than 4000000.
If you want a bit of magic, you can also build on the fact that every 3rd Fibonacci number is even, on the basis of "even+odd=>odd", "odd+even=>odd", and only "odd+odd=>even":
0 1 1 2 3 5 8...
E O O E O O E
^ O+O
^ E+O
^ O+E
^ O+O
var prev=1;
var curr=2;
var sum=0;
while(curr<4000000){
sum+=curr;
console.log("elem: "+curr,"sum: "+sum);
for(var i=0;i<3;i++){
var temp=prev;
prev=curr;
curr+=temp;
}
}
And if the question would be only the title, Addition of even fibonacci numbers (let's say, n of them), pure mathematics could do the job, using Binet's formula (described in #Silerus' answer) and the fact that it is an (a^n-b^n)/c thing, where a^n and b^n are geometric sequences, every 3rd of them also being a geometric sequence, (a^3)^n, and the sum of geometric sequences has a simple, closed form (if the series is a*r^n, the sum is a*(1-r^n)/(1-r)).
Putting everything together:
// convenience for JS->C
var pow=Math.pow;
var sqrt=Math.sqrt;
var round=Math.round;
var s5=sqrt(5);
var a=(1+s5)/2;
var a3=pow(a,3);
var b=(1-s5)/2;
var b3=pow(b,3);
for(var i=0;i<12;i++){
var nthEvenFib=round((pow(a3,i)-pow(b3,i))/s5);
var sumEvenFibs=round(((1-pow(a3,i+1))/(1-a3)-(1-pow(b3,i+1))/(1-b3))/s5);
console.log("elem: "+nthEvenFib,"sum: "+sumEvenFibs);
}
Again, both snippets become rather C-ish if var-s are replaced with some C-type, int-s in the first snippet, and mostly double-s in this latter one (the loop variable i can be a simple int of course).
You can use the Binet formula in your calculations - this will allow you to abandon the slow recursive algorithm, another option may be a non-recursive algorithm for calculating fibonacci numbers. https://en.wikipedia.org/wiki/Jacques_Philippe_Marie_Binet. Here is an example of using the Binet formula, it will be much faster than the recursive algorithm, since it does not recalculate all previous numbers.
#include <iostream>
#include <math.h>
using namespace std;
int main(){
double num{},a{(1+sqrt(5))/2},b{(1-sqrt(5))/2},c{sqrt(5)};
int sum{};
for (auto i=1;i<30;++i){
num=(pow(a,i)-pow(b,i))/c;
if (static_cast<int>(num)%2==0)
sum+=static_cast<int>(num);
}
cout<<sum;
return 0;
}
variant 2
int fib_sum(int n)
{
int sum{};
if (n <= 2) return 0;
std::vector<int> dp(n + 1);
dp[1] = 1; dp[2] = 1;
for (int i = 3; i <= n; i++)
{
dp[i] = dp[i - 1] + dp[i - 2];
if(dp[i]%2==0)
sum+=dp[i];
}
return sum;
}
You can speed up brutally by using compile time precalculations for all even Fibonacci numbers and sums using constexpre functions.
A short check with Binets formula shows, that roundabout 30 even Fibonacci numbers will fit into a 64bit unsigned value.
30 numbers can really easily been procealculated without any effort for the compiler. So, we can create a compile time constexpr std::array with all needed values.
So, you will have zero runtime overhead, making you program extremely fast. I am not sure, if there can be a faster solution. Please see:
#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>
// ----------------------------------------------------------------------
// All the following wioll be done during compile time
// Constexpr function to calculate the nth even Fibonacci number
constexpr unsigned long long getEvenFibonacciNumber(size_t index) {
// Initialize first two even numbers
unsigned long long f1{ 0 }, f2{ 2 };
// calculating Fibonacci value
while (--index) {
// get next even value of Fibonacci sequence
unsigned long long f3 = 4 * f2 + f1;
// Move to next even number
f1 = f2;
f2 = f3;
}
return f2;
}
// Get nth even sum of Fibonacci numbers
constexpr unsigned long long getSumForEvenFibonacci(size_t index) {
// Initialize first two even prime numbers
// and their sum
unsigned long long f1{ 0 }, f2{ 2 }, sum{ 2 };
// calculating sum of even Fibonacci value
while (--index) {
// get next even value of Fibonacci sequence
unsigned long long f3 = 4 * f2 + f1;
// Move to next even number and update sum
f1 = f2;
f2 = f3;
sum += f2;
}
return sum;
}
// Here we will store ven Fibonacci numbers and their respective sums
struct SumOfEvenFib {
unsigned long long fibNum;
unsigned long long sum;
friend bool operator < (const unsigned long long& v, const SumOfEvenFib& f) { return v < f.fibNum; }
};
// We will automatically build an array of even numbers and sums during compile time
// Generate a std::array with n elements taht consist of const char *, pointing to Textx...Texty
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
return std::array<SumOfEvenFib, sizeof...(ManyIndices)>{ { {getEvenFibonacciNumber(ManyIndices + 1), getSumForEvenFibonacci(ManyIndices + 1)}...}};
};
// You may check with Ninets formula
constexpr size_t MaxIndexFor64BitValue = 30;
// Generate the reuired number of texts
constexpr auto generateArray()noexcept {
return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}
// This is an constexpr array of even Fibonacci numbers and its sums
constexpr auto SOEF = generateArray();
// ----------------------------------------------------------------------
int main() {
// Show sum for 4000000
std::cout << std::prev(std::upper_bound(SOEF.begin(), SOEF.end(), 4000000))->sum << '\n';
// Show all even numbers and their corresponding sums
for (const auto& [even, sum] : SOEF) std::cout << even << " --> " << sum << '\n';
return 0;
}
Tested with MSVC 19, clang 11 and gcc10
Compiled with C++17
Welcome to Stack Overflow :)
I have only modified your code on the loop, and kept your Fibonacci implementation the same. I've verified the code's answer on Project Euler. The code can be found below, and I hope my comments help you understand it better.
The three things I've changed are:
1) You tried to look for a number all the way until the 4,000,000 iteration rather than for the number that is less than 4,000,000. That means your program probably went crazy trying to add a number that's insanely large (which we don't need) <- this is probably why your program threw in the towel
2) I improved the check for even numbers; we know that fibonacci sequences go odd odd even, odd odd even, so we only really need to add every third number to our sum instead of checking if the number itself is even <- modulus operations are very expensive on large numbers
3) I added two lines that are commented out with couts, they can help you debug and troubleshoot your output
There's also a link here about using Dynamic Programming to solve the question more efficiently, should anyone need it.
Good luck!
#include <iostream>
using namespace std;
int fibonacci(int i) {
if (i == 2)
return 2;
else if (i == 1)
return 1;
else return fibonacci(i - 1) + fibonacci(i - 2);
}
int main() {
// need to add the sum of all even fib numbers under a particular sum
int max_fib_number = 4000000;
int currentTerm, sum = 0;
currentTerm = 1;
int i = 1;
// we do not need a for loop, we need a while loop
// this is so we can detect when our current number exceeds fib
while(currentTerm < max_fib_number) {
currentTerm = fibonacci(i);
//cout << currentTerm <<"\n";
// notice we check here if currentTerm is a valid number to add
if (currentTerm < max_fib_number) {
//cout << "i:" << i<< "\n";
// we only want every third term
// this is because 1 1 2, 3 5 8, 13 21 34,
// pattern caused by (odd+odd=even, odd+even=odd)
// we also add 1 because we start with the 0th term
if ((i+1) % 3 == 0)
sum += currentTerm;
}
i++;
}
cout << sum;
return 0;
}
Here's Your modified code which produce correct output to the project euler's problem.
#include <iostream>
using namespace std;
int fibonacci(int i) {
if (i == 2)
return 2;
else if (i == 1)
return 1;
else return fibonacci(i - 1) + fibonacci(i - 2);
}
int main() {
int currentsum, sum = 0;
for (int i = 1; i <= 100; i++) {
currentsum = fibonacci(i);
//here's where you doing wrong
if(sum >= 4000000) break; //break when sum reaches 4mil
if(currentsum %2 == 0) sum+=currentsum; // add when even-valued occurs in the currentsum
}
cout << sum;
return 0;
}
Output 4613732
Here's my Code which consists of while loop until 4million occurs in the sum with some explanation.
#include <iostream>
using namespace std;
int main()
{
unsigned long long int a,b,c , totalsum;
totalsum = 0;
a = 1; // 1st index digit in fib series(according to question)
b = 2; // 2nd index digit in fib series(according to question)
totalsum+=2; // because 2 is an even-valued term in the series
while(totalsum < 4000000){ //loop until 4million
c = a+b; // add previous two nums
a = b;
b = c;
if(c&1) continue; // if its odd ignore and if its an even-valued term add to totalsum
else totalsum+=c;
}
cout << totalsum;
return 0;
}
for people who downvoted, you can actually say what is wrong in the code instead downvoting the actual answer to the https://projecteuler.net/problem=2 is the output of the above code 4613732 , competitive programming itself is about how fast can you solve problems instead of clean code.
I am trying to find an efficient way to, given a number n, print the first number of the following series greater or equal to n:
0, 0+1, 0+1+2, 0+1+2+3, 0+1+2+3+4, ... = 0, 1, 3, 6, 10, ...
For example, 2 would return 3, and 7 (or 8, or 9) would return 10.
There's surely a smart way to solve it... Could you help me? Thanks in advance!
The following code returns the correct solutions, but it is not efficient enough for this problem:
#include <iostream>
using namespace std;
int main(){
int n;
while(cin >> n){
int m = 0;
for(int i = 1;m < n; ++i){
m = m + i;
}
cout << m << endl;
}
}
You are describing triangular numbers!
y = (x*(x + 1)) / 2;
To get the next number in the series given y, you could solve for x
x = ceil((sqrt(1+8y)-1)/2);
Then throw x back into the 1st formula to get your answer!
This is a good approach for large numbers but may not be ideal for smaller numbers
Basically you want to write program for Arithmetic progression (AP) i.e. sum of first n numbers
int main(){
int n;
while(cin >> n){
int m = (n * (n + 1)) / 2;
cout << m << endl;
}
}
This question already has answers here:
How to get the least number after deleting k digits from the input number
(11 answers)
Closed 6 years ago.
I am trying to code a program that can do something like this:
in:
5 4
1 9 9 9 0
out:
9990
and i have a problem. It doesnt work on any set of numbers. For example it works for the one above, but it doesnt work for this one:
in:
15 9
2 9 3 6 5 8 8 8 8 7 2 2 8 1 4
out: 988887814
2 9 3 6 5 8 8 8 8 7 2 2 8 1 4
I did this with a vector approach and it works for any set of numbers, but i'm trying to do it a stack for a better complexity.
EDIT ---- MODIFIED FOR STD::STACK
Code for method using stack:
#include <iostream>
#include <fstream>
#include <stack>
using namespace std;
ifstream in("trompeta.in");
ofstream out("trompeta.out");
void reverseStack(stack<char> st) {
if(!st.empty())
{
char x = st.top();
st.pop();
reverseStack(st);
out<<x;
}
return;
}
int main()
{
int n,m,count=1;
stack <char> st;
char x;
in>>n>>m;
in>>x;
st.push(x);
for(int i=1; i<n; i++)
{
in>>x;
if(st.top()<x && count+n-i-1>=m)
{
st.pop();
st.push(x);
}
else
{
st.push(x);
count++;
if (count>m-1) break;
}
};
reverseStack(st);
}
Code for method using vectors:
#include <iostream>
#include <fstream>
using namespace std;
ifstream in ( "trompeta.in" );
ofstream out ( "trompeta.out" );
int main ()
{
int i = 0, N, M, max, j, p = 0, var;
in >> N >> M;
char* v = new char[N];
char* a = new char[M];
in >> v;
var = M;
max = v[0];
for ( i = 0; i < M; i++ )
{
for ( j = p ; j < N-var+1; j++ )
{
if ( v[j] > max )
{
max = v[j];
p = j;
}
}
var--;
a[i] = max;
max = v[p+1];
p = p+1;
}
for ( i = 0; i < M; i++ )
out << a[i]-'0';
}
Can any1 help me to get the STACK code working?
Using the fact that the most significant digit completely trumps all other digets except in place of a tie, I would look at the first (N-M+1) digits, find the largest single digit in that range.
If it occurs once, the first digit is locked in. Discard the digits which occur prior to that position, and you repeat for "maximum value of M-1 numbers of out N-position" to find the remaining digits of the answer. (or N-position-1, if position is zero based)
If it occurs multiple times, then recursively find "maximum value of M-1 numbers out of N-position" for each, then select the largest single result from these. There can be at most N such matches.
I forgot to mention, if N==M, you are also done.
proof of recursion:
Computing the value of the sub-match will always select M-1 digits. When M is 1, you only need to select the largest of a few positions, and have no more recursion. This is true for both cases. Also the "select from" steps always contain no more than N choices, because they are always based on selecting one most significant digit.
------------------ how you might do it with a stack ----------------
An actual implementation using a stack would be based on an object which contains the entire state of the problem, at each step, like so:
struct data { // require: n == digits.size()
int n, m;
std::string digits;
bool operator<(const data &rhs){ return digits < rhs.digits; }
};
The point of this is not just to store the original problem, but to have a way to represent any subproblem, which you can push and pop on a stack. The stack itself is not really important, here, because it is used to pick the one best result within a specific layer. Recursion handles most of the work.
Here is the top level function which hides the data struct:
std::string select_ordered_max(int n, int m, std::string digits) {
if (n < m || (int)digits.size() != n)
return "size wrong";
data d{ n, m, digits };
data answer = select_ordered_max(d);
return answer.digits;
}
and a rough pseudocode of the recursive workhorse
data select_ordered_max(data original){
// check trivial return conditions
// determine char most_significant
// push all subproblems that satisfy most_significant
//(special case where m==1)
// pop subproblems, remembering best
return answer {original.m, original.m, std::string(1, most_significant) + best_submatch.digits };
}
String comparison works on numbers when you only compare strings of the exact same length, which is the case here.
Yes, I know having n and m is redundant with digits.size(), but I didn't want to work too hard. Including it twice simplified some recursion checks. The actual implementation only pushed a candidate to the stack if it passed the max digit check for that level of recursion. This allowed me to get the correct 9 digit answer from 15 digits of input with only 28 candidates pushed to the stack (and them popped during max-select).
Now your code has quite a few issues, but rather than focusing on those lets answer the question. Let's say that your code has been corrected to give us:
const size_t M where M is the number of digits expected in our output
const vector<int> v which is the input set of numbers of size N
You just always want to pick the highest value most significant number remaining. So we'll keep an end iterator to prevent us from picking a digit that wouldn't leave us with enough digits to finish the number, and use max_element to select:
const int pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
auto maximum = 0;
auto end = prev(cend(v), M - 1);
auto it = max_element(cbegin(v), end);
for (auto i = M - 1; i > 0; --i) {
maximum += *it * pow10[i];
advance(end, 1);
it = max_element(next(it), end);
}
maximum += *it;
Live Example
This code depends upon M being greater than 0 and less than N and less than log10(numeric_limits<int>::max())
EDIT: Sad to say this solves the consecutive digits problem, after edits the question wants subsequent digits, but not necessarily consecutive
So the little known numeric library provides inner_product which seems like just the tool for this job. Now your code has quite a few issues, but rather than focusing on those lets answer the question. Let's say that your code has been corrected to give us:
vector<int> foo(M) where M is the number of digits expected in our output
const vector<int> v which is the input set of numbers of size N
We'll use foo in the inner_product, initializing it with decreasing powers of 10:
generate(begin(foo), end(foo), [i=int{1}]() mutable {
auto result = i;
i *= 10;
return result; });
We can then use this in a loop:
auto maximum = 0;
for (auto it = prev(rend(v), size(foo) + 1); it != rbegin(v); advance(it, -1)) {
maximum = max<int>(inner_product(cbegin(foo), cend(foo), it, 0), maximum);
}
maximum = max<int>(inner_product(cbegin(foo), cend(foo), rbegin(v), 0), maximum);
Live Example
To use it's initialization requires that your initial M was smaller than N, so you may want to assert that or something.
--EDITED--
here's my suggestion with STACK based on my previous suggestion using vector
findMaxValueOutOfNDigits(stackInput, M, N)
{
// stackInput = [2, 9, 3, 6, 5, 8, 8, 8, 8, 7, 2, 2, 8, 1, 4]
// *where 4 was the first element to be inserted and 2 was the last to be inserted
// if the sequence is inverted, you can quickly fix it by doing a "for x = 0; x < stack.length; x++ { newStack.push(stack.pop()) }"
currentMaxValue = 0
for i = 0; i < (M - N + 1); i++
{
tempValue = process(stackInput, M, N)
stackInput.pop()
if (tempValue > currentMaxValue)
currentMaxValue = tempValue
}
return currentMaxValue
}
process(stackInput, M, N)
{
tempValue = stackInput.pop() * 10^(N - 1)
*howManyItemsCanILook = (M - N + 1)
for y = (N - 2); y == 0; y++
{
currentHowManyItemsCanILook = *howManyItemsCanILook
tempValue = tempValue + getValue(stackInput, *howManyItemsCanILook) * 10^(y)
*howManyItemsCanILook = *howManyItemsCanILook - 1
for x = 0; x < (currentHowManyItemsCanILook - *howManyItemsCanILook); x++
{
stackInput.pop()
}
}
return tempValue
}
getValue(stackInput, *howManyItemsCanILook)
{
currentMaxValue = stackInput.pop()
if (currentMaxValue == 9)
return 9
else
{
goUntil = *howManyItemsCanILook
for i = 0; i < goUntil; i++
{
*howManyItemsCanILook = *howManyItemsCanILook - 1
tempValue = stackInput.pop()
if (currentMaxValue < tempValue)
{
currentMaxValue = tempValue
if (currentMaxValue == 9)
return currentMaxValue
}
}
return currentMaxValue
}
}
note: where *howManyItemsCanILook is passed by reference
I hope this helps
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.
#include <iostream>
using namespace std;
int main() {
int i =1;
int j =2;
int k = 0;
while (k<4000000)
{
k = i +j;
i = k+j;
j=i +k;
}
cout << i <<endl;
cout << j << endl;
cout << k << endl;
return 0;
}
Am I even doing this correctly? Why am I getting three different nu
You want to find the sum of even terms in Fibonacci sequence, you can use a function that uses recursion, but that will take more time than your code since recursion will compute the Fibonacci for each element and won't store the Fibonacci of the previous numbers.
But if you want to use your code, this will be faster for the compilation to your process, but I thing your code must be like this.
int even=2;
while (k<4000000 && i<4000000 && j<4000000)
{
k = i+j; //3 13 55 i,j and k computes Fibonacci
i = k+j; //5 21 89 of sequence of numbers so
j = i+k; //8 34 144 they must differ :)
if(k%2==0)even+=k;
if(i%2==0)even+=i;
if(j%2==0)even+=j;
}
if(k>=4000000 && k%2==0)even-=k;
if(j>=4000000 && j%2==0)even-=j;
if(i>=4000000 && i%2==0)even-=i;
cout<<"even sum equals"<<even;
}
You can this code to find desired output
int evenFibSum(int limit)
{
if (limit < 2)
return 0;
// Initialize first two even prime numbers
// and their sum
long long int ef1 = 0, ef2 = 2;
long long int sum = ef1 + ef2;
// calculating sum of even Fibonacci value
while (ef2 <= limit)
{
// get next even value of Fibonacci sequence
long long int ef3 = 4*ef2 + ef1;
// If we go beyond limit, we break loop
if (ef3 > limit)
break;
// Move to next even number and update sum
ef1 = ef2;
ef2 = ef3;
sum += ef2;
}
return sum;
}