Related
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 working on a program in which I must print out the number of primes, including 1 and 239, from 1 - 239 ( I know one and or two may not be prime numbers, but we will consider them as such for this program) It must be a pretty simple program because we have only gone over some basics. So far my code is as such, which seems like decent logical flow to me, but doesnt produce output.
#include <iostream>
using namespace std;
int main()
{
int x;
int n = 1;
int y = 1;
int i = 0;
while (n<=239)
{x = n % y;
if (x = 0)
i++;
if (y < n)
y++;
n++;
while (i == 2)
cout << n;
}
return 0;
}
The way I want this to work is to take n, as long as n is 239 or less, and preform modulus division with every number from 1 leading up to n. Every time a number y goes evenly into n, a counter will be increased by 1. if the counter is equal to 2, then the number is prime and we print it to the screen. Any help would be so greatly appreciated. Thanks
std::cout << std::to_string(2) << std::endl;
for (unsigned int i = 3; i<240; i += 2) {
unsigned int j = 3;
int sq = sqrt(i);
for (; j <= sq; j += 2) if (!(i%j)) break;
if (j>sq) std::cout << std::to_string(i) << std::endl;
}
first of all, the prime definition: A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
so you can skip all the even numbers (and hence ... i+=2).
Moreover no point to try to divide for a number greater than sqrt(i), because then it will have a divisor less than sqrt(i) and the code finds that and move to the next number.
Considering only odd numbers, means that we can skip even numbers as divisors (hence ... j+=2).
In your code there are clearly beginner errors, like (x = 0) instead of x==0. but also the logic doesn't convince. I agree with #NathanOliver, you need to learn to use a debugger to find all the errors. For the rest, good luck with the studies.
lets start with common errors:
first you want to take input from user using cin
cin>>n; // write it before starting your while loop
then,
if (x = 0)
should be:
if (x == 0)
change your second while loop to:
while (i == 2){
cout << n;
i++;
}
I am making a random number generator. It asks how many digits the user wants to be in the number. for example it they enter 2 it will generate random numbers between 10 and 99. I have made the generator but my issue is that the numbers are not unique.
Here is my code. I am not sure why it is not generating unique number. I thought srand(time(null)) would do it.
void TargetGen::randomNumberGen()
{
srand (time(NULL));
if (intLength == 1)
{
for (int i = 0; i< intQuantity; i++)
{
int min = 1;
int max = 9;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
else if (intLength == 2)
{
for (int i = 0; i<intQuantity; i++)
{
int min = 10;
int max = 90;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
if (intLength == 3)
{
for (int i = 0; i<intQuantity; i++)
{
int min = 100;
int max = 900;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
else if (intLength == 4)
{
for (int i = 0; i<intQuantity; i++)
{
int min = 1000;
int max = 9000;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
if (intLength == 5)
{
for (int i = 0; i<intQuantity; i++)
{
int min = 10000;
int max = 90000;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
else if (intLength == 6)
{
for (int i = 0; i<intQuantity; i++)
{
int min = 100000;
int max = 900000;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
if (intLength == 7)
{
for (int i = 0; i<intQuantity; i++)
{
int min = 1000000;
int max = 9000000;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
else if (intLength == 8)
{
for (int i = 0; i <intQuantity; i++)
{
int min = 10000000;
int max = 89999999;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
if (intLength == 9)
{
for (int i = 0; i < intQuantity; i++)
{
int min = 100000000;
int max = 900000000;
int number1 = rand();
if (intQuantity > max)
{
intQuantity = max;
}
cout << number1 % max + min << "\t";
}
}
}
Okay so I thought I figured out a way to do this without arrays but It isn't working before I switch to the fisher yates method. Can someone tell me why this isn't working? It is supposed to essentially take the random number put that into variable numGen. Then in variable b = to numgen. Just to hold what numGen used to be so when the loop goes through and generates another random number it will compare it to what the old number is and if it is not equal to it, then it will output it. If it is equal to the old number than rather than outputting it, it will deincrement i so that it will run through the loop without skipping over the number entirely. However, when I do this is infinitely loops. And I am not sure why.
if (intLength == 1)
{
for (int i = 0; i< intQuantity; ++i)
{
int min = 1;
int max = 9;
int number1 = rand();
int numGen = number1 % max + min;
if (intQuantity > max)
{
intQuantity = max;
}
for (int k = 0; k < 1; k++)
{
cout << numGen << "\t";
int b = numGen;
}
int b = numGen;
if (b != numGen )
{
cout << numGen << "\t";
}
else
{
i--;
}
}
}
Everyone has interesting expectations for random numbers -- apparently, you expect random numbers to be unique! If you use any good random number generator, your random numbers will never be guaranteed to be unique.
To make this most obvious, if you wanted to generate random numbers in the range [1, 2], and you were to generate two numbers, you would (normally expect to) get one of the following four possibilities with equal probability:
1, 2
2, 1
1, 1
2, 2
It does not make sense to ask a good random number generator to generate the first two, but not the last two.
Now, take a second to think what to expect if you asked to generate three numbers in the same range... 1, 2, then what??
Uniqueness, therefore, is not, and will not be a property of a random number generator.
Your specific problem may require uniqueness, though. In this case, you need to do some additional work to ensure uniqueness.
One way is to keep a tab on which numbers are already picked. You can keep them in a set, and re-pick if you get one you got earlier. However, this is effective only if you pick a small set of numbers compared to your range; if you pick most of the range, the end of the process gets ineffective.
If the number count you are going to pick corresponds to most of the range, then using an array of the range, and the using a good shuffling algorithm to shuffle the numbers around is a better solution. (The Fisher-Yates shuffle should do the trick.)
Hint 0:
Use Quadratic residue from number theory; an integer q is called a quadratic residue modulo p if it is congruent to a perfect square modulo p; i.e., if there exists an integer x such that:
x2 ≡ q (mod p)
Hint 1:
Theorem: Assuming p is a prime number, the quadratic residue of x is unique as long as 2x < p. For example:
02 ≡ 0 (mod 13)
12 ≡ 1 (mod 13)
22 ≡ 4 (mod 13)
32 ≡ 9 (mod 13)
42 ≡ 3 (mod 13)
52 ≡ 12 (mod 13)
62 ≡ 10 (mod 13)
Hint 2:
Theorem: Assuming p is a prime number such that p ≡ 3 (mod 4), not only x2%p (i.e the quadratic residue) is unique for 2x < p but p - x2%p is also unique for 2x>p. For example:
02%11 = 0
12%11 = 1
22%11 = 4
32%11 = 9
42%11 = 5
52%11 = 3
11 - 62%11 = 8
11 - 72%11 = 6
11 - 82%11 = 2
11 - 92%11 = 7
11 - 102%11 = 10
Thus, this method provides us with a perfect 1-to-1 permutation on the integers less than p, where p can be any prime such that p ≡ 3 (mod 4).
Hint 3:
unsigned int UniqueRandomMapping(unsigned int x)
{
const unsigned int p = 11; //any prime number satisfying p ≡ 3 (mod 4)
unsigned int r = ((unsigned long long) x * x) % p;
if (x <= p / 2) return r;
else return p - r;
}
I didn't worry about the bad input numbers (e.g. out of the range).
Remarks
For 32-bit integers, you may choose the largest prime number such that p ≡ 3 (mod 4) which is less than 232 which is 4294967291.
Even though, this method gives you a 1-to-1 mapping for generating random number, it suffers from the clustering issue.
To improve the randomness of the aforementioned method, combine it with
other unique random mapping methods such as XOR operator.
I'll assume you can come up with a way to figure out how many numbers you want to use. It's pretty simple, since a user input of 2 goes to 10-99, 3 is 100-999, etc.
If you want to come up with your own implementation of unique, randomly generated numbers, check out these links.
http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Here is a very similar implementation: https://stackoverflow.com/a/196065/2142219
In essence, you're creating an array of X integers, all set to the value of their index. You randomly select an index between 0 and MAX, taking the value at this index and swapping it with the max value. MAX is then decremented by 1 and you can repeat it by randomly selecting an index between 0 and MAX - 1.
This gives you a random array of 0-999 integers with no duplicates.
Here are two possible approaches to generating unique random numbers in a range.
Keep track of which numbers you have already generated using std::set, and throw away and regenerate numbers as long as they are already in the set. This approach is not recommended if you want to generate a large number of random numbers, due to the birthday paradox.
Generate all numbers in your given range, take a random permutation of them, and output however many the user wants.
Standard random generators would never generate unique numbers, in this case they would Not be independent.
To generate unique numbers you have to:
Save all number generated and compare new one with old ones, if there is coincidence - regenerate.
or
Use random_shuffle function: http://en.cppreference.com/w/cpp/algorithm/random_shuffle to get all sequence in advance.
Firstly, srand()/rand() commonly have a period of 2^32, which means that after calling srand(), rand() will internally iterate over distinct integers during the first 2^32 calls to rand(). Still, rand() may well return a result with less than 32 bits: such as an int between 0 and RAND_MAX where RAND_MAX is 2^31-1 or 2^15-1, so you may see repeated results as the caller of rand(). You probably read about the period though, or somebody's comment made with awareness of that, and somehow it's been mistaken as uniqueness....
Secondly, given any call to rand() generates a number far larger than you want, and you're doing this...
number1 % max
The result of "number1 % max" is in the range 0 <= N <= max, but the random number itself may have been any multiple of max greater than that. In other words, two distinct random numbers that differ by a multiple of max still produce the same result for number1 % max in your program.
To get distinct random numbers within a range, you could prepopulate a std::vector with all the numbers, then std::shuffle them.
Here's the problem.
Write the given number N, as sum of the given numbers, using only additioning and subtracting.
Here's an example:
N = 20
Integers = 8, 15, 2, 9, 10
20 = 8 + 15 - 2 + 9 - 10.
Here's my idea;
First idea was to use brute force, alternating plus and minus. First I calculate the number of combinations and its 2^k (where k is the nubmer of integers), because I can alternate only minus and plus. Then I run through all numbers from 1 to 2^k and I convert it to binary form. And for any 1 I use plus and for any 0 I use minus. You'll get it easier with an example (using the above example).
The number of combinations is: 2^k = 2^5 = 32.
Now I run through all numbers from 1 to 32.
So i get: 1=00001, that means: -8-15-2-9+10 = -24 This is false so I go on.
2 = 00010, which means: -8-15-2+9-10 = -26. Also false.
This method works good, but when the number of integers is too big it takes too long.
Here's my code in C++:
#include <iostream>
#include <cmath>
using namespace std;
int convertToBinary(int number) {
int remainder;
int binNumber = 0;
int i = 1;
while(number!=0)
{
remainder=number%2;
binNumber=binNumber + (i*remainder);
number=number/2;
i=i*10;
}
return binNumber;
}
int main()
{
int N, numberOfIntegers, Combinations, Binary, Remainder, Sum;
cin >> N >> numberOfIntegers;
int Integers[numberOfIntegers];
for(int i = 0; i<numberOfIntegers; i++)
{
cin >>Integers[i];
}
Combinations = pow(2.00, numberOfIntegers);
for(int i = Combinations-1; i>=Combinations/2; i--) // I use half of the combinations, because 10100 will compute the same sum as 01011, but in with opposite sign.
{
Sum = 0;
Binary = convertToBinary(i);
for(int j = 0; Binary!=0; j++)
{
Remainder = Binary%10;
Binary = Binary/10;
if(Remainder==1)
{
Sum += Integers[numberOfIntegers-1-j];
}
else
{
Sum -= Integers[numberOfIntegers-1-j];
}
}
if(N == abs(Sum))
{
Binary = convertToBinary(i);
for(int j = 0; Binary!=0; j++)
{
Remainder = Binary%10;
Binary = Binary/10;
if(Sum>0)
{
if(Remainder==1)
{
cout << "+" << Integers[numberOfIntegers-1-j];
}
else
{
cout << "-" << Integers[numberOfIntegers-1-j];
}
}
else
{
if(Remainder==1)
{
cout << "-" << Integers[numberOfIntegers-1-j];
}
else
{
cout << "+" << Integers[numberOfIntegers-1-j];
}
}
}
break;
}
}
return 0;
}
Since this is typical homework, I'm not going to give the complete answer. But consider this:
K = +a[1] - a[2] - a[3] + a[4]
can be rewritten as
a[0] = K
a[0] + a[2] + a[3] = a[1] + a[4]
You now have normal subset sums on both sides.
So what you are worried about is you complexity .
Lets analyse what optimisations can be done.
Given n numbers in a[n] and target Value T;
And it is sure one combination of adding and subtracting gives you T ;
So Sigma(m*a[k]) =T where( m =(-1 or 1) and 0 >= k >= n-1 )
This just means ..
It can written as
(sum of Some numbers in array) = (Sum of remaining numbers in array) + T
Like in your case..
8+15-2+9-10=20 can be written as
8+15+9= 20+10+2
So Sum of all numbers including target = 64 // we can cal that .. :)
So half of it is 32 as
Which if further written as 20+(somthing)=32
which is 12 (2+10) in this case.
Your problem can be reduced to Finding the numbers in an array whose sum is 12 in this case
So your problem now can be reduced as find the combination of numbers whose sum is k (which you can calculate as described above k=12 .) For Which the complexity is O(log (n )) n as size of array , Keep in mind that you have to sort array and use binary search based algo for getting O(log(n)).
So as complexity can be made from O(2^n) to O((N+1)logN)as sorting included.
This takes static input as you have provided and i have written using core java
public static void main(String[] args) {
System.out.println("Enter number");
Scanner sc = new Scanner(System.in);
int total = 0;
while (sc.hasNext()) {
int[] array = new int[5] ;
for(int m=0;m<array.length;m++){
array[m] = sc.nextInt();
}
int res =array[0];
for(int i=0;i<array.length-1;i++){
if((array[i]%2)==1){
res = res - array[i+1];
}
else{
res =res+array[i+1];
}
}
System.out.println(res);
}
}
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;
}