fibonacci series gone wrong? - c

we have been asked to write a program to generate fibonacci series as our homework.
so i wrote a program that generates the first n fibonacci numbers .here is my frist code that dosent work properly
# include <stdio.h>
void main()
{
int a = -1, b = 1, c = 0, i, n, sum = 0 ;
printf("Enter the limit : ") ;
scanf("%d", &n) ;
printf("\nThefibonacci series is : \n\n") ;
for(i = 1 ; i <= n ; i++)
{
c = a + b ;
printf("%d \t", c) ;
b=c;
a=b;
}
}
so i tried various combinations and i found out that my code would work well if i interchanged the 12th and 13th lines. i.e
# include <stdio.h>
void main()
{
int a = -1, b = 1, c = 0, i, n, sum = 0 ;
printf("Enter the limit : ") ;
scanf("%d", &n) ;
printf("\nThefibonacci series is : \n\n") ;
for(i = 1 ; i <= n ; i++)
{
c = a + b ;
printf("%d \t", c) ;
a=b;
b=c;
}
}
It is the same logic right.
why does the first code give me wrong output?
what are segmentation faults?(my compiler frequently tells me that there are segmentation faults in my code)
P.S-i am a begginer.Just three weeks into c language and we are learning about loops.

The ordering of statements matters.
b = c;
a = b;
When this runs, b and a will both be equal to the original value of c, and the old value of b has been lost. This is probably not what you wanted.
a = b;
b = c;
When this runs, a will equal the old value of b, and b will equal the original value of c.

In Fibonacci series, a new number is generated as sum of previous two numbers.
Lets say previous two numbers were A and B and the newly generated number is C. Now for the next iteration you need to forget A and B & C are your new previous numbers.
To make B and C you new A and B you need to do:
A = B // B becomes the new A
B = C // C becomes the new B
what you are doing is:
B = C // C becomes the new B, but you've not saved the old value of B!!!
A = B // Old value of B gone..B is now C, which is assigned to A

Lines are executed in order, so in the first example b becomes c before a becomes b, in effect you are assigning c to both a and b creating some kind of exponential series (but of zeroes) instead of the fibonacci sequence.
A segmentation fault means that your program is accessing memory somewhere where it is not allowed to access memory, usually because you are dereferencing an invalid pointer or accessing an array out of bounds.

Look at this in isolation:
c = a + b ;
printf("%d \t", c) ;
b=c;
a=b;
The value of both a and bafter performing this will be c.
c = a + b ;
printf("%d \t", c) ;
a=b;
b=c;
If you re-arrange the statements, a gets the old value of b, and b gets the new value of c.

It is the same logic right. why does the first code give me wrong output?
Have you ever wondered, why
printf("Enter the limit : ") ;
scanf("%d", &n) ;
printf("\nThe fibonacci series is : \n\n") ;
first outputs Enter the limit, then waits for you to input a number, then outputs The fibonacci series is – in that particular order?
Why not the other way around or everything at the same time?
What are segmentation faults?
A simple google search would have given you tons of explanations. It means you have accessed memory, that is not yours to access.

Related

seemingly ignored assignment to variables in head of for-loop

void main()
{
int a, b, r;
//Finf GCD by Eucledian algorithm
scanf("%d %d", &a, &b);
for( ; b == 0; (a = b), (b = r)){
r = a % b;
printf("GCD is %d", a);
}
printf("GCD is %d", a);
}
Somehow this doesn't work.
I assign a to b and b to r, but this doesn't seem to change the value of a or b.
This for(;b==0;(a=b),(b=r)) sets up the for-loop like this
do nothing to init anything
as long as b equals 0 do the loop body
between loop body executions first copy value of b to a,
then copy value of r to b
Note that the loop will never execute if b starts off non-zero.
Otherwise the loop will stop executing as soon as b becomes non-zero, from being updated with value of r.
(This is somewhat compiling an answer from comments, in order to get this out of the list of unanswered questions. Credits to dddJewelsbbb. I offer to delete this if they make an answer and ask me to.)
Find the corrected working code below, which changes the loop condition:
#include <stdio.h>
void main ()
{
int a, b, r;
//Finf GCD by Eucledian algorithm
scanf ("%d %d", &a, &b);
for (; r > 0; a = b, b = r)
{
r = a % b;
}
printf ("GCD is %d", a);
}
Test by giving inputs: 16, 12
16
12
GCD is 4
Code explanation:
The code is the direct implementation of Euclid's algorithm to find GCD. Here the divisor (one of the number) is used to obtain a remainder (after dividing the second number as dividend). Next, the remainder becomes the divisor and the earlier divisor becomes the dividend and this process continues till remainder is zero.
There is plenty of scope in the code to make it more elegant and handle corner cases. I corrected the exact same code as minimum as possible to spot the exact error (which was in the for loop condition).

Linear Complexity in my program?

Some time ago I ask in codereview.stackexchange a review for one of my problems. I din't get a sufficient answer and many people told me to post a question here just to get more answers and solutions. My problem is the follwoing.
Giving a dynamic array, we want to pass the array elements from a
file. The first number in the file N gives us the array length. They
follow N numbers, the actual elements of the array.
Three brothers are going to work in the shop of their father for a time. The >shop is doing well and every day generates profit which the
three brothers may provide. The brothers agreed that they would divide
the total time in three successive parts, not necessarily equal
duration, and that each one will be working in the shop during one of
these parts and collects the corresponding profit on his behalf. But
they want to make a deal fairly, so that one received from three more
profit someone else. Specifically, they want to minimize the profit
the most favored of the three will receive.
Now I created a solution with O(n^2) complexity but I want to know if someone has any other idea to solve the problem with linear complexity.
Lets assume we have the follwoing input :
1 1 8 1 1 3 4 9 5 2
The output is 15.
A=1+1+8+1+1+3 , B=4+9=13 , C=5+2=7
Remenber I want linear complexity. If someone believe it's just a homework to be done and I boring then he has no place here. I just want to know if someone has any idea how to solve the problem in C.
My try was the following:
#include <stdio.h>
#include <limits.h>
#define max(A,B,C) A > (B > C ? B : C) ? A : (B > C ? B : C)
#define N 10
int main()
{
int e[N] = {1, 1, 8, 1, 1, 3, 4, 9, 5, 2 };
int i=0;
int j = N-1;
int A = e[i];
int C = e[j];
int B = 0;
int x, AL, CR, BL, BR, m, mp = INT_MAX, L, R;
for(x = i+1 ; x < j; x++) B+=e[x];
m = max(A,B,C);
printf("A=%d B=%d C=%d\n", A, B, C);
while(m < mp)
{
AL = A+e[i+1];
CR = C+e[j-1];
BL = B-e[i+1];
BR = B-e[j-1];
L = max(AL,BL,C);
R = max(A,BR,CR);
if(L<R)
{
A=AL;
B=BL;
i++;
}
else
{
C=CR;
B=BR;
j--;
}
mp = m;
m = max(A,B,C);
printf("A=%d B=%d C=%d MAX=%d\n", A, B, C, m);
}
printf("%d", mp);
return 0;
}
I don't want someone to base in the above code cause it gives wrong outputs in 90% of the most inputs.

How to sum two rows of a 2D array element by element like a sum of vectors in C language?

I would like to know if there is any simple way to sum two rows of a 2D array in C without using a loop. I got the following sample code in the main function
for (i = 0; i < 3; i++) {
(*A)[i] = drand48();
(*B)[i] = drand48();
}
I'm using two pointers (A and B) to an array of length 3, and after initializing them with random numbers I want to sum them in a single sentence (like a vector sum). Let C be another pointer to an array of length 3. I have tried
(*C) = (*A) + (*B);
But I'm getting an error with that. In fortran, one can do it simply by putting:
C = A + B
Assuming A, B, and C are arrays of the same length, and both A and B are initilized. Or, if we want to sum two rows of a 2Darray, we can put:
C = A(i,:) + A(j,:)
which sum the row i to the row j.
So, there's a analogous way in C??
Thaks for your help.
There are several things you should understand: First, fortran compiles a loop for you, so when its code runs it is still looping through the data. Second, an optimizer might do some work for you by "un-rolling" the loop. You could write your code that essentially unrolls a small loop, as:
for (i = 0; i < 2; i++) {
C[i][0] = A[i][0] + B[i][0];
C[i][1] = A[i][1] + B[i][1];
C[i][2] = A[i][2] + B[i][2];
}
However, the same number of adds is still executed whether you code in Fortran, Matlab (a vector oriented language) or C (with or without loop unrolling).
I got this to function.
More or less, there is an error in the sumline at the end of each line.
#include <stdio.h>
int main ()
//2D_Array. Create 2D array . Multiplication in each array slot.
//KHO2016.no4. mingw (TDM-GCC-32) . c-ansi .
{
//Declare
int a,b,c,d,sum;
int k,l,num_array[50][50];
//vaulate
jump1 :
printf ("Coordinat system Descartes\nBasically two FOR-loops.\n\n");
printf ("Plot X no. of Columns, Horizontal axis. Then Y no. of Rows, Vertical axis\n:\n");
scanf ("%d %d",&a,&b); //a = vertical , b=Horizontal.
printf ("\nPlot two no. to be multipled\n:\n");
scanf ("%d %d",&c,&d);
//calculate
for (l=0;l<b;l++) // l counts lines or on Y axis .
{for (k=0;k<a;k++) // k counts colums (on each line) .
printf ("[Y%d] [X%d] (%d * %d = %d)\t: ",l,k,c++,d,c*(d));
sum = (sum+(c*d++));
printf ("sum %d",sum);
printf ("\n");}
printf ("\n");
goto jump1;
//terminate
return 0;
}
Here one can select a coordinate,
and obtain the value of the selected coordinate.
But no sum of each line .
#include <stdio.h>
int main ()
//2D_Array.(float). Select Coordinate, and obtain slot Value .
//KHO2016.no6. mingw (TDM-GCC-32) . c-ansi .
{
//declare
int aa,c,d,p,q;
float j,ar_d[10][10];
//valuate
jump0:
printf ("Select 1, 2, 3, 4 : ");
scanf ("%d",&aa);
if (aa==1&&2&&3)
goto jump0;
//calculate
if (aa==4)
{for (c=0;c<10;c++)
for (d=0;d<10;d++)
ar_d[c][d]=(float)d/c;
for (c=0;c<10;c++)
{for (d=0;d<10;d++)
printf ("(Y%d X%d.%.1d/%.1d= %.2f) ",c,d,c,d,ar_d[c][d]);
printf ("SumLine1(%d)/(%d) = %.2f\n",c,d,j);
j=(float)d/(c+1);}
printf ("\nSelect a Coordinate : first X then Y\n");
scanf("%d%d",&p,&q);
printf ("Coordinate X[%d],Y[%d] has this value : %f\n",p,q,ar_d[q][p]);}
goto jump0;
//terminate
return 0;
}

C Program Runs Surprisingly Slow

A simple program I wrote in C takes upwards of half an hour to run. I am surprised that C would take so long to run, because from what I can find on the internet C ( aside from C++ or Java ) is one of the faster languages.
// this is a program to find the first triangular number that is divisible by 500 factors
int main()
{
int a; // for triangular num loop
int b = 1; // limit for triangular num (1+2+3+......+b)
int c; // factor counter
int d; // divisor
int e = 1; // ends loop
long long int t = 0; // triangular number in use
while( e != 0 )
{
c = 0;
// create triangular number t
t = t + b;
b++;
// printf("%lld\n", t); // in case you want to see where it's at
// counts factors
for( d = 1 ; d != t ; d++ )
{
if( t % d == 0 )
{
c++;
}
}
// test to see if condition is met
if( c > 500 )
{
break;
}
}
printf("%lld is the first triangular number with more than 500 factors\n", t);
getchar();
return 0;
}
Granted the program runs through a lot of data, but none of it is ever saved, just tested and passed over.
I am using the Tiny C Compiler on Windows 8.
Is there a reason this runs so slowly? What would be a faster way of achieving the same result?
Thank you!
You're iterating over a ton of numbers you don't need to. By definition, a positive factor is any whole number that can be multiplied by another to obtain the desired product.
Ex: 12 = 1*12, 2*6, and 3*4
The order of multiplication are NOT considered when deciding factors. In other words,
Ex: 12 = 2*6 = 6*2
The order doesn't matter. 2 and 6 are factors once.
The square root is the one singleton that will come out of a factoring of a product that stands alone. All others are in pairs, and I hope that is clear. Given that, you can significantly speed up your code by doing the following:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// this is a program to find the first triangular number that is divisible by 500 factors
int main()
{
int c = 0; // factor counter
long long int b = 0; // limit for triangular num (1+2+3+......+b)
long long int d; // divisor
long long int t = 0; // triangular number in use
long long int r = 0; // root of current test number
while (c <= 500)
{
c = 0;
// next triangular number
t += ++b;
// get closest root.
r = floor(sqrt(t));
// counts factors
for( d = 1 ; d < r; ++d )
{
if( t % d == 0 )
c += 2; // add the factor *pair* (there are two)
}
if (t % r == 0) // add the square root if it is applicable.
++c;
}
printf("%lld is the first triangular number with more than 500 factors\n", t);
return 0;
}
Running this on IDEOne.com takes less than two seconds to come up with the following:
Output
76576500 is the first triangular number with more than 500 factors
I hope this helps. (and I think that is the correct answer). There are certainly more efficient ways of doing this (see here for some spoilers if you're interested), but going with your code idea and seeing how far we could take it was the goal of this answer.
Finally, this finds the first number with MORE than 500 factors (i.e. 501 or more) as per your output message. Your comment at the top of the file indicates you're looking for the first number with 500-or-more, which does not match up with your output message.
Without any math analysis:
...
do
{
c = 0;
t += b;
b++;
for (d = 1; d < t; ++d)
{
if (!(t % d))
{
c++;
}
}
} while (c <= 500);
...
You are implementing an O(n^2) algorithm. It would be surprising if the code took less than a half an hour.
Refer to your computer science textbook for a better method compared to this brute force method of: check 1, 1 + 2, 1 + 2 + 3, etc.
You might be able to shorten the inner for loop. Does it really need to check all the way up to t for factors that divide the triangular number. For example, can 10 be evenly divisible by any number greater than 5? or 100 by any number greater than 50?
Thus, given a number N, what is the largest number that can evenly divide N?
Keep reading/researching this problem.
Also, as other people have mentioned, the outer loop could be simply coded as:
while (1)
{
// etc.
}
So, no need need to declare e, or a? Note, this doesn't affect the length of time, but your coding style indicates you are still learning and thus a reviewer would question everything your code does!!
You are doing some unnecessary operations, and I think those instructions are not at all required if we can check that simply.
first :
while(e!=0)
as you declared e=1, if you put only 1 in loop it will work. You are not updating value of e anywhere.
Change that and check whether it works fine or not.
One of the beautiful things about triangle numbers, is that if you have a triangle number, with a simple addition operation, you can have the next one.

Explain the working of a program that prints the GCD and LCD of two numbers

I know its very simple but I can't find out what the variable t is for.
int main() {
int a, b, x, y, t, gcd, lcm;
printf("Enter two integers\n");
scanf("%d%d", &x, &y);
a = x;
b = y;
while (b != 0) {
t = b;
b = a % b;
a = t;
}
gcd = a;
lcm = (x*y)/gcd;
printf("Greatest common divisor of %d and %d = %d\n", x, y, gcd);
printf("Least common multiple of %d and %d = %d\n", x, y, lcm);
return 0;
}
If I remove the usage of variable t, the input has to be given in decreasing order (i.e. highest input first). If t is used everything works fine. I am very new to programming so please help.
This is Euclid's Algorithm for calculating the GCD.
function gcd(a, b){
while (b ≠ 0){
t := b;
b := a mod t;
a := t;
}
return a
}
This logic reduces the value of a and b. t is a dummy variable holding the value of b, while the next new value of b is being calculated. Which will be even less in magnitude. So eventually we will be able to terminate the algorithm with the required result.
In this t is for temporary holding.
In this while loop a%b has to be set to b, and b's value has to be set to a.
To avoid loss of b's value.
Say you have 2 values - old 'a' and old 'b' (no 't').
The 'while' loop is supposed to update those values to new 'a' and new 'b'.
Every recalculation of new 'a' requires old 'b', and every recalculation of new 'b' requires old 'a'.
However, if you calculate 'b' first, it overwrites the old value and you can't calculate 'a' correctly. Same goes the other way around - recalculate new 'a', you lose the old value and can't use it to calculate 'b'. Therefore you need a temporary variable in which to store the old value of whichever variable ('a' or 'b') you recalculate first in an iteration, then use this cached value for calculating the other :) 't' is this temporary variable.
The use of a temporary variable is a common programming idiom. It is used to hold a copy of a variable's value so that the value can be used later after the variable is updated with a different value. Perhaps the simplest use case is the swap, also known as exchange.
/* swap the values held by a and b */
t = b; /* t holds the value in b */
b = a; /* b gets the value in a */
a = t; /* a gets the value in t */
The logic of the while loop is not fundamentally different from the illustration above.
The algorithm that is implemented is Euclid's algorithm. It is based on the division theorem, which states that for positive a and b, there exists q such that a = q*b + r and 0 <= r < b. In C, r can be computed with a % b.
In the case that a is smaller than b, then a % b is a. So, the algorithm allows a and b to switch positions at the next iteration.
If you want a formulation of the algorithm without a temporary, you can use a circular buffer instead.
int r[3] = { a, b, a % b };
int i = 0;
while (r[(i + 2) % 3]) {
++i;
r[(i + 2) % 3] = r[i % 3] % r[(i + 1) % 3];
}
gcd = r[(i + 1) % 3];
According to your program's logic,
Consider two numbers - 2 and 3.
To calculate the GCD,
Calculate 2 % 3. The result is 2 (which is not 0) so continue.
Calculate 3 % result => 3 % 2. The result is 1 (which is not 0) so continue.
Calculate 2 % result => 2 % 1. This answer is 0. Thus our GCD is the second number (i.e) 1.
So basically, your t helps you store the second number in each iteration so that in the next iteration, your first number (i.e. the number to the left of the '%' operator) was the previous iteration's second number. (I hope that didn't confuse the crap out of you)
All this is necessary because you're overwriting the second number in each iteration with the result of the '%' operation.

Resources