Exactly one high card in a 6 card hand using simulations - c

So I've got a probability problem that (out of pure boredom) I decided to try and solve using simulations.
Problem: What is the probability of drawing exactly one high card in a 6 card hand.
Now, this problem is specifically about some game that's played in my country so for some weird reason there are 21 high cards, but that's not important.
Solving this problem by hand, using basic combinatorics I got:
And now, here's the way I simulated it in C:
The main function:
int main(void)
{
srand(time(0));
int deck[52];
int i;
for(i = 0; i<21; i++) deck[i] = 1;
for(i = 21; i<52; i++) deck[i] = 0;
int n;
printf("# of simulations: ");
scanf("%d", &n);
int memo[52];
int hits = 0;
for(i = 0; i<n; i++){
clear_memo(memo);
hits += simulate(deck, memo);
}
printf("Result: %lf\n", (double)hits/n);
}
So the deck is an array of 52 numbers where the first 21 have the value 1 (high cards) and the other 31 elements have the value 0 (low cards).
The memo will be sent to the simulation function each time to keep track of which cards have already been drawn. The memo also gets reset every time using the clear_memo function which does nothing but set all the values to zero.
Then it calls the simulation functions and counts the hits.
Here's the simulation function:
int simulate(int * deck, int * memo){
//I draw the first card separetly in order to initialize the had_high variable
int index = ( rand() % 52 );
int card = deck[index];
int had_high = (card == 1);
memo[index] = 1;
//printf("%d ", index);
int i = 1;
while(i < 6){
int draw = (rand() % 52);
//printf("%d ", draw);
if(memo[draw]) continue;
index = draw;
card = deck[index];
memo[index] = 1;
if(card){
if(had_high) { //meaning there are 2 high cards, no hit
//printf("\n");
return 0;
}
had_high = 1; //if not, then this is the first high card
}
i++;
}
printf("\n");
return had_high; //the function would've reached this point even if all the cards had been low
//therefore I return had_high instead of just 1
}
The simulation function itself works, I've tested it separately a lot of times and there seem to be no problems with it.
However, when I run the program with a high number of simulations (100k or 1m) the result is always approx. 0.175 which is not what I got with my by hand calculation.
I am reasonably certain that my by hand calculation is correct (but correct me if I'm wrong there as well).
If I'm right about the by hand calculations then there must be something wrong with how I simulated this event. One of my thoughts was that it had something to do with the rand function and how it's pseudo-random, but I really don't know as it is very hard to test anything that works with random numbers.
Any ideas?
Thanks.
EDIT:
As per request of klutt:
void clear_memo(int * memo){
int i = 0;
for(;i<52;i++) memo[i] = 0;
}

My program gives the same result as yours - about 0.175
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int deck[52];
int successes = 0;
srand((unsigned)time(NULL));
for(int run = 0; run < 100000; run++) {
for(int n = 0; n<52; n++) {
deck[n] = n;
}
int cards = 52;
int highs = 0;
for(int n=0; n<6; n++) {
int index = rand() % cards;
if(deck[index ] < 21) {
highs++;
}
deck[index] = deck[--cards];
}
if(highs == 1) {
successes++;
}
}
printf("Probability of drawing exactly one high card = %f\n", successes / 100000.0);
}
But the combinatrics are wrong in two ways:
There are only 31 "low" cards in the pack so the expression should be
21 31 30 29 28 27
__ . __ . __ . __ . __ . __ = 0.02921
52 51 50 49 48 47
Secondly, any of the 6 draws can be a "high", not just the first, so
multiply the chance by 6.
0.02921 * 6 = 0.1752

Your calculation is wrong
What you are calculating is the probability that the first card is high and all of the rest are low. Or at least it seams that you're trying to do so. You're slightly off. It should be (21/52)*(31/51)*(30/50)*(29/49)*(28/48)*(27/47) = 0.02921...
You should multiply this by 6, since the high card can appear anywhere. Then you have the probability for exactly one high, which is 0.17526
rand() % n has a non-uniform distribution
That being said, be aware that the random generator in C is not very good to use in this way. Depending on how you use it it can get a horrible distribution. If you are using C++, you can use:
std::random_device rd;
std::default_random_engine generator(rd());
std::uniform_int_distribution<int> distribution(0,51);
int index = distribution(generator);
In simulations like this, this may have a huge effect. In this case it had a small effect. I tested both the standard rand() method and the C++ variant and ran the simulation 4 times with 10 million iterations each time:
Using rand() % 52:
Result: 0.175141
Result: 0.175074
Result: 0.175318
Result: 0.175506
Using distribution(generator):
Result: 0.175197
Result: 0.175225
Result: 0.175228
Result: 0.175293
As you can see, the deviation is smaller. So if accuracy matters, either consider switching to C++ and use those methods, or find a way to get a good distribution. And if you are doing a simulation to numerically calculate a probability, then it does matter.

Related

How can I use the rand() function to generate a different number that hasn't been generated before?

// What I mean by this is shown by my example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int i;
int a;
for (a = 0;a <10;a ++) {
i = (rand()%10)+1; // generates a number from 1-10
printf("%d\n", i);
}
// I would like for the loop to generate a number that gives a number that was not generated before. For example, an output such as:
1,3,6,2,8,9,4,10,5,7
instead of:
3,9,10,3,7,9,2,7,10,1
In other words, I would like no copies.
You obviously don't just want no copies, but you want every number in a given set exactly once. This is, as commented by Robert, similar to shuffling a deck of cards. You don't have "decks" in C, but you can model one as an array:
int deck[] = {1,1,1,1,1,1,1,1,1,1};
This should represent 10 different "cards" (identified by their index in the array), each available one time. Now, just write code that "draws" cards:
int i = 0; // starting point for searching for the next card to draw
for (int n = 10; n > 0; --n) // how many cards are left
{
int skip = rand() % n; // randomly skip 0 .. n cards
while (1)
{
if (deck[i]) // card still available?
{
if (!skip) break; // none more to skip -> done
--skip; // else one less to skip
}
if (++i > 9) i = 0; // advance index, wrapping around to 0
}
deck[i] = 0; // draw the card
printf("%d\n", i+1); // and print it out
}
of course, seed the PRNG (e.g. srand(time(0))) first, so you don't get the same sequence every time.
The idea shown in the question is to print numbers within a range, without repetition. Here is one way to do that, by putting each value into an array and swapping its elements around.
A variation could be that you don't want to use all the possible numbers, in that case just change PICKED.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRLEN 10
#define PICKED 10
int main(void) {
int array[ARRLEN];
srand((unsigned)time(NULL)); // seed the PRNG
for(int i = 0; i < ARRLEN; i++) { // generate the numbers
array[i] = i + 1;
}
for(int i = 0; i < ARRLEN; i++) { // shuffle the array
int index = rand() % ARRLEN;
int temp = array[i];
array[i] = array[index]; // by randomly swapping
array[index] = temp;
}
for(int i = 0; i < PICKED; i++) { // output the numbers
printf("%d ", array[i]);
}
printf("\n");
}
Program output:
9 8 4 5 1 10 7 3 6 2
The library's PRNG is not very random, but for many cases that is not important. If it is, better algorithms are available.

Ising 1-Dimensional C - program

i am trying to simulate the Ising Model 1-D. This model consists in a chain of spin (100 spins) and using the Mont Carlo - Metropolis to accept the flip of a spin if the energy of the system (unitary) goes down or if it will be less than a random number.
In the correct program, both the energy the magnetization go to zero, and we have the results as a Gaussian (graphics of Energyor the magnetization by the number of Monte Carlo steps).
I have done some work but i think my random generator isn't correctt for this, and i don't know how/where to implement the boundary conditions: the last spin of the chain is the first one.
I need help to finish it. Any help will be welcome. Thank you.
I am pasting my C program down:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h> //necessary for function time()
#define LENGTH 100 //size of the chain of spins
#define TEMP 2 // Temperature in units of J
#define WARM 200 // Termalização
#define MCS 20000 //Monte Carlo Steps
void start( int spin[])
{
/* starts with all the spins 1 */
int i;
for (i = 0 ; i < 100; i++)
{
spin[i] = 1;
}
}
double energy( int spin[]) //of the change function J=1
{
int i;
double energyX=0;// because the begining Energy = -J*sum (until 100) =-100,
for (i = 0;i<100;i++)
energyX=energyX-spin[i]*spin[i+1];
return(energyX);
}
int randnum(){
int num;
srand(time(NULL));
/* srand(time(NULL)) objectives to initiate the random number generator
with the value of the function time(NULL). This is calculated as being the
total of seconds passed since january first of 1970 until the present date.
So, this way, for each execution the value of the "seed" will be different.
*/
srand(time(NULL));
//picking one spin randomly zero to 100
num=rand() % 100;
printf("num = %d ", num);
return num;
}
void montcarlo( int spin[])
{
int i,j,num;
double prob;
double energyA, energyB; // A -> old energy and B -> the new energy
int rnum1,rnum2;
prob=exp(-(energyB-energyA)/TEMP);
energyA = 0;
energyB = 0;
for (i = 0;i<100;i++)
{
for (j = 0;j<100;j++)
{
energyA=energy(spin);
rnum1=randnum();
rnum2=randnum(); // i think they will give me different numbers
spin[rnum1] = -spin[rnum1]; //flip of the randomly selected spin
energyB = energyB-spin[j]*spin[j+1];
if ((energyB-energyA<0)||((energyB-energyA>0)&&(rnum2>prob))){ // using rnum2 not to be correlated if i used rnum1
spin[rnum1]=spin[rnum1];} // keep the flip
else if((energyB-energyA>0)&&(rnum2<prob))
spin[rnum1]=-spin[rnum1]; // unflip
}
}
}
int Mag_Moment( int spin[] ) // isso é momento magnetico
{
int i;
int mag;
for (i = 0 ; i < 100; i++)
{
mag = mag + spin[i];
}
return(mag);
}
int main()
{
// starting the spin's chain
int spin[100];//the vector goes til LENGHT=100
int i,num,j;
int itime;
double mag_moment;
start(spin);
double energy_chain=0;
energy_chain=energy(spin); // that will give me -100 in the begining
printf("energy_chain starts with %f", energy_chain);// initially it gives -100
/*Warming it makes the spins not so ordered*/
for (i = 1 ; i <= WARM; i++)
{
itime = i;
montcarlo(spin);
}
printf("Configurtion after warming %d \n", itime);
for (j = 0 ; j < LENGTH; j++)
{
printf("%d",spin[j]);
}
printf("\n");
energy_chain=energy(spin); // new energy after the warming
/*openning a file to save the values of energy and magnet moment of the chain*/
FILE *fp; // declaring the file for the energy
FILE *fp2;// declaring the file for the mag moment
fp=fopen("energy_chain.txt","w");
fp2=fopen("mag_moment.txt","w");
int pures;// net value of i
int a;
/* using Monte Carlo metropolis for the whole chain */
for (i = (WARM + 1) ; i <= MCS; i++)
{
itime=i;//saving the i step for the final printf.
pures = i-(WARM+1);
montcarlo(spin);
energy_chain = energy_chain + energy(spin);// the spin chain is moodified by void montcarlo
mag_moment = mag_moment + Mag_Moment(spin);
a=pures%10000;// here i select a value to save in a txt file for 10000 steps to produce graphs
if (a==0){
fprintf(fp,"%.12f\n",energy_chain); // %.12f just to give a great precision
fprintf(fp2,"%.12f\n",mag_moment);
}
}
fclose(fp); // closing the files
fclose(fp2);
/* Finishing -- Printing */
printf("energy_chain = %.12f\n", energy_chain);
printf("mag_moment = %.12f \n", mag_moment);
printf("Temperature = %d,\n Size of the system = 100 \n", TEMP);
printf("Warm steps = %d, Montcarlo steps = %d \n", WARM , MCS);
printf("Configuration in time %d \n", itime);
for (j = 0 ; j < 100; j++)
{
printf("%d",spin[j]);
}
printf("\n");
return 0;
}
you should call srand(time(NULL)); only once in your program. Every time you call this in the same second you will get the same sequence of random numbers. So it is very likely that both calls to randnum will give you the same number.
Just add srand(time(NULL)); at the begin of main and remove it elsewhere.
I see a number of bugs in this code, I think. The first one is the re-seeding of the srand() each loop which has already been addressed. Many of the loops go beyond the array bounds, such as:
for (ii = 0;ii<100;ii++)
{
energyX = energyX - spin[ii]*spin[ii+1];
}
This will give you spin[99]*spin[100] for the last loop, for which is out of bounds. That is kind of peppered throughout the code. Also, I noticed the probability rnum2 is an int but compared as if it's supposed to be a double. I think dividing the rnum2 by 100 will give a reasonable probability.
rnum2 = (randnum()/100.0); // i think they will give me different numbers
The initial probability used to calculate the spin is, prob=exp(-(energyB-energyA)/TEMP); but both energy values are not initialized, maybe this is intentional, but I think it would be better to just use rand(). The Mag_Moment() function never initializes the return value, so you wind up with a return value that is garbage. Can you point me to the algorithm you are trying to reproduce? I'm just curious.

C: Random walk (Brownian motion) program does not return expected theoretical value. Why?

This is just an experiment based on section 6-3 in "Feynman Lectures on Physics":
In its simplest version, we imagine a “game” in which a “player”
starts at the point x=0 and at each “move” is required to take a step
either forward (toward +x) or backward (toward −x). The choice is to
be made randomly, determined, for example, by the toss of a coin.
Source: http://www.feynmanlectures.caltech.edu/I_06.html#Ch6-S3
My objective is to calculate the expected distance from the stating point. So, I suppose that each step is equal to one unit of distance. I wrote a simple C program to simulate 30 random steps, then calculate the final distance from the starting point. This is repeated for a million times, and the program averages the distance to get the expected distance.
Theoretically, the expected distance should be the square root of the number of the steps. That should be about sqrt(30) = 5.48.
However, the program is run few times and keeps returning a value near to 4.33 (to be more exact, 4.33461, 4.33453, and 4.34045). Why is it not even near to the theoretical value of about 5.48?
Here is my code:
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
int main ( int argc, char *argv[] )
{
int number_of_steps = 30;
int repetition = 1000000;
int distance = 0;
int total_distance = 0;
double expected_distance;
int i, j;
srand(time(NULL));
for ( i = 0; i < repetition; i++ ) {
for ( j = 0; j < number_of_steps; j++) {
distance += rand() & 1 ? -1 : 1;
}
total_distance += abs(distance);
distance = 0;
}
expected_distance = (float) total_distance / i;
printf ( "%g\n", expected_distance );
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
From the lecture you linked to, your theoretical expectation is based on the root mean square, which is different from the arithmetic mean, which is what you have coded. By changing the algorithm from one to the other, the code now gives you the expected results.
for ( i = 0; i < repetition; i++ ) {
for ( j = 0; j < number_of_steps; j++) {
distance += rand() & 1 ? -1 : 1;
}
total_distance += distance * distance;
distance = 0;
}
expected_distance = sqrt((float) total_distance / repetition);
printf ( "%g\n", expected_distance );
return EXIT_SUCCESS;
}
The answer to this post suggests that using the low-order bit(s) of rand() is unlikely to be a great choice.
I'd try a different way of generating your +1 or -1.

How to give struct objects random not matching x and y coordinates in C?

I am trying to do my homework, which is some sort of game.
This is a part of it and I'm trying to create a function which puts 18 (9 in one team and the other 9 in another) different players on the field. player is a struct which has a name and coordinates. So I tried to write this function and had several problems. I think I have mostly fixed them, but I don't understand what's wrong with it now. Basically this function gives all the players random x and y coordinates, but as I have to make sure that they don't match, I created 2 lists x's and y's. The program takes all the players and add's their x coordinates to x's list if the current player x coordinate matches any x coordinates in x's list, then the program checks the same player's y coordinate and checks if it matches the coordinate of y of the same object in y's list. So if both x and y math, then the program runs again by recursion. The problem I get is that the coordinates I get every time I run the program are same. they don't match but they are not really random cause they don't change when I run them again.
I think I have tried all my knowledge and skills but still can't understand the problem of my code.
Can you please tell me what's wrong with this code?
void random_positions()
{
int i,j;
int xs[17],ys[17];
for(i= 0; i<9 ; i++)
{
players[i][0].x = rand() % 25;
players[i][0].y = rand() % 25;
players[i][1].x = rand() % 25;
players[i][1].y = rand() % 25;
printf("A%d x = %d y = %d \n",i+1,players[i][0].x,players[i][0].y);
printf("B%d x = %d y = %d \n",i+1,players[i][1].x,players[i][1].y);
}
for(i = 0; i < 9 ; i++)
{
xs[i] = players[i][0].x;
xs[i+8] = players[i][1].x;
ys[i] = players[i][0].y;
ys[i+8] = players[i][1].y;
for(j = 0; j <= i ; j++)
{
//printf("j%d start\n",j);
if(i != j && xs[i] == xs[j])
{
//printf("i%d start\n",j);
if(ys[i] == ys[j])
{
return random_positions();
}
//("j%d done\n",j);
}
//printf("j%d done\n",j);
}
}
}
A computer is (usually) a deterministic machine; if you run the same program twice, you will get the same answer.
A random number generator generally takes a seed, an initial value that it uses to initialize itself before it starts producing random numbers; give it a different seed, and you will get a different sequence. One way to do this is to give it the current time as a seed:
#include <stdio.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
int main ()
{
/* initialize random seed: */
srand (time(NULL));
/* generate random number between 1 and 10: */
int num = rand() % 10 + 1;
printf("%d\n", num);
return 0;
}

What is Sum of Even Terms In Fibonacci (<4million)? [Large Value Datatype Confusion]

By starting with 1 and 2, the first 10 terms of Fibonacci Series 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 4 million.
Now, I got the idea for how to do this. But I'm confused about the data types to hold such big data. I'm getting weird results with int. :(
MORE: Its Project Euler 2nd question. But I can't get it. I get crazy values as answer. Can someone please post the ideal program?
EDIT: Here's what I wrote for just printing Fibonacci to screen. Bare Basic. My variable goes crazy even when I give 100 for the limit. Is my code wrong?
// Simple Program to print Fibonacci series in Console
#include <stdio.h>
int main() {
int x=1,y=2,sum=0,limit=0,i=0,temp=0;
printf("Enter Limit:");
scanf("%d",&limit);
if(limit==1)
printf("%d",x);
else if(limit>1) {
printf("%d %d",x,y);
if (limit>2) {
while (i<limit-2) {
temp=y;
sum=x+y;
x=temp;
y=sum;
printf(" %d",sum);
i++;
}
}
}
printf("\n");
return 0;
}
SOLVED: Actually, I managed to get the solution myself. Here's my program. It works.
#include <stdio.h>
int main() {
int x=1,y=2,sum,limit; //Here value of first 2 terms have been initialized as 1 and 2
int evensum=2; //Since in calculation, we omit 2 which is an even number
printf("Enter Limit: "); //Enter limit as 4000000 (4million) to get desired result
scanf("%d",&limit);
while( (x+y)<limit ) {
sum=x+y;
x=y;
y=sum;
if (sum%2==0)
evensum+=sum;
}
printf("%d \n",evensum);
return 0;
}
Since you only want up to four million, it's likely that int is not your problem.
It's quite possible that your program is buggy and that the data storage is just fine, so you should test your program on smaller values. For example, it's clear that the sum of the first three even terms is 44 (hint: every third term is even) so if you run your program with a cap of 50, then you should instantly get 44 back. Keep running small test cases to get confidence in the larger ones.
For security, use the 'long' data type; the C standard requires that to hold at least 4 billion, but on most machines, 'int' will also hold 4 billion.
enum { MAX_VALUE = 4000000 };
int sum = 0;
int f_n0 = 0;
int f_n1 = 1;
int f_n2;
while ((f_n2 = f_n0 + f_n1) < MAX_VALUE)
{
if (f_n2 % 2 == 0)
sum += f_n2;
f_n0 = f_n1;
f_n1 = f_n2;
}
printf("%d\n", sum);
I am not a programmer, but here's an adaptation to Leffler's code without the IF-criterion. It should work for MAX_VALUES above 2 (given there are no mistakes in programming syntax), based on a pattern I found in the even-only fibonacci series: 0,2,8,34,144,610,2584... so interestingly: f_n2 = 4*f_n1 + f_n0. This also means this program only needs 1/3rd of the calculations, since it doesn't even consider/calculate the odd fibonacci numbers.
enum { MAX_VALUE = 4000000 };
int sum = 2;
int f_n0 = 0;
int f_n1 = 2;
int f_n2 = 8;
while (f_n2 < MAX_VALUE)
{
sum += f_n2;
f_n0 = f_n1;
f_n1 = f_n2;
f_n2 = 4*f_n1 + f_n0;
}
printf("%d\n", sum);
Try changing this:
while (i<limit-2)
to this:
while (y<limit)
As written, your program is cycling until it gets to the 4 millionth Fibonacci number (i.e. when i gets to 4 million, though overflow obviously happens first). The loop should check to see when y (the larger Fibonacci number) becomes greater than 4 million.
Guys, I got the answer. I confirmed the result and int can handle it. Here's my program:
#include <stdio.h>
int main() {
int x=1,y=2,sum,limit; //Here value of first 2 terms have been initialized as 1 and 2
int evensum=2; //Since in calculation, we omit 2 which is an even number
printf("Enter Limit: "); //Enter limit as 4000000 (4million) to get desired result
scanf("%d",&limit);
while( (x+y)<limit ) {
sum=x+y;
x=y;
y=sum;
if (sum%2==0)
evensum+=sum;
}
printf("%d \n",evensum);
return 0;
}
Thx for all the replies and help. "Thinking on my feet" to the rescue :)
An amusing solution is to use the closed form for Fibonacci sequences and the closed form for geometric progressions. The end solution looks like this:
sum = ( (1-pow(phi_cb, N+1)) / (1-phi_cb) - (1-pow(onephi_cb,N+1)) / (1-onephi_cb)) / sqrt(5);
where
double phi = 0.5 + 0.5 * sqrt(5);
double phi_cb = pow(phi, 3.0);
double onephi_cb = pow(1.0 - phi, 3.0);
unsigned N = floor( log(4000000.0 * sqrt(5) + 0.5) / log(phi) );
N = N / 3;
with all the caveats regarding double to int-type conversions of course.
int is big enough for values in the millions on almost every modern system, but you can use long if you are worried about it. If that still gives you weird results, then the problem is with your algorithm.
Use BigInt.
Then again, unsigned int stores values up to over 4 billion, so you shouldn't be having any problems even with "sum of all fibonacci numbers up to 4 million" (which, obviously, has to be less than 8 mil)?
Your program prints F_1 + ..+ F_limit and not F_1 + ... F_n with F_n < limit as you described.
Check the Wikipedia article on Fibonacci Numbers and Sloane A000045: Fibonacci numbers grows exponentially. Checking this table F_48 = 4807526976 which exceeds int. F_100 is 354224848179261915075 which surely overflows even int64_t (your stack doesn't, though).
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.
int main()
{
long first = 1, second = 2, next, c;
int sum=0;
for ( c = 1 ; c <100000000; c++ )
{
next = first + second;
if(next>=4000000)
{
next= next-second;
break;
}
first = second;
second = next;
if(next%2==0){
sum=sum+next;
}
}
printf("the sum of even valued term is %d\n",sum+2);
}
Here's my program:
#include <iostream>
long int even_sum_fibonacci(int n){
int i = 8;
int previous_i = 2;
int next_i = 0;
long int sum = previous_i + i;;
while(n>next_i){
next_i = i*4 + previous_i;
previous_i = i;
i = next_i;
sum = sum + i;
}
return sum - next_i; //now next_i and i are both the bigger number which
//exceeds 4 million, but we counted next_i into sum
//so we'll need to substract it from sum
}
int main()
{
std::cout << even_sum_fibonacci(4000000) << std::endl;
return 0;
}
Because if you look at the fibonacci series (at the first few even numbers)
2 8 34 144 610 2584 ... you'll see that it matches the pattern that
next_number = current_number * 4 + previous_number.
This is one of solutions. So the result is 4613732
You can try the below code.
public static void SumOfEvenFibonacciNumbers()
{
int range = 4000000;
long sum = 0;
long current = 1;
long prev = 0;
long evenValueSum= 0;
while (evenValueSum< range)
{
sum = prev + current;
prev = current;
current = sum;
if (sum % 2 == 0 )
{
evenValueSum = evenValueSum+ sum;
}
}
Console.WriteLine(evenValueSum);
}
You can use the above code.
import numpy as np
M = [[0,1],[1,1]]
F = [[0],[1]]
s = 0
while(F[1][0] < 4000000):
F = np.matmul(M, F)
if not F[0][0]%2:
s+=F[0][0]
print(s)
We can do better than this in O(log n) time. Moreover, a 2 × 2 matrix and a two dimensional vector can be multiplied again in O(1) time. Therefore it suffices to compute Mn.
The following recursive algorithm computes Mn
If n = 0, return I2
If n = 1, return M.
If n = 2m.
Recursively compute N = Mm, and set P = N2.
If n = 2m+1, set P = PM.
Return P.
We have T(n) = T(n/2) + O(1), and by master's theorem T(n) = O(log n)
You can also use recurrence for Even Fibonacci sequence is:
EFn = 4EFn-1 + EFn-2
with seed values
EF0 = 0 and EF1 = 2.
SIMPLE SOLUTION WOULD BE:-
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int n1=1;
int n2=2;
int num=0,sum;
for (int i=1;i,n1<4000000;i++)
{
cout<<" "<<n1;
num=n1+n2;
if(!(n1%2))
{
sum+=n1;
}
n1=n2;
n2=num;
}
cout<<"\n Sum of even term is = "<<sum;
return 0;
}
Here's my offer, written in Java. I had been using a for loop whose exit value was 4000000 but realized early on there was a serious overflow for the sum of the numbers. Realizing the Fibonacci Number has to be less than 4 million (and not the sum), I changed to a while loop and got it:
class Main {
public static void main(String[] args) {
int counter = 0;
int fibonacciSum = 0, fibonacciNum = 0;
int previous = 1, secondPrevious = 0;
fibonacciNum = previous + secondPrevious;
while (fibonacciNum <= 4000000){
if (fibonacciNum % 2 == 0 ){
counter++;
fibonacciSum += fibonacciNum;
secondPrevious = previous;
previous = fibonacciNum;
}//ends if statement
else {
secondPrevious = previous;
previous = fibonacciNum;
}//ends else statement
fibonacciNum = previous + secondPrevious;//updates number
}//ends loop
System.out.println("\n\n\n" + fibonacciSum);
}//ends main method
}//ends Main

Resources