sum of even terms in the fibonacci series less than 4 million - c

////Even Fibonacci numbers
int i=2;
int sum_of_Even=0;
int fib_array[]={};
fib_array[0]=1;
fib_array[1]=1;
while (fib_array[i]<4000000)
{
fib_array[i]=fib_array[i-1]+fib_array[i-2];
if ((fib_array[i]%2) == 0)
{
sum_of_Even+=fib_array[i];
}
i++;
}
printf("sum of Even terms in the fib sequence = %i\n", sum_of_Even);
On the terminal, the output is 3.. Help!
Program looks good...but somehow gives an output of 3 (which is pretty wrong)..
Open to suggestions on how to fix this..
Thanks..

The problem is likely here: (Anyway this is a big problem even if it is not the problem.)
int fib_array[]={};
The space allocated for your array in memory will not grow dynamically as you appear to expect. You need to manage the memory for it somehow. Right now you are overflowing this array substantially and it is amazing that this program does not crash or segfault.
Edit: Moreover, every time your while loop checks its condition for whether to run again, it accesses an entry in your array which has not been initialized! Note:
On the first run, it checks whether fib_array[2] < 4000000, which you are about to set in the body of the loop!
On the second run, it checks whether fib_array[3] < 4000000, which you are about to set in the body of the loop!
Etc.
Edit 2: Since (amazingly many) people have been posting that you need to use a 64 bit integer and that this is the source of your problems, I'd like to make the clarifying remark that the answer is in the 5 million range, so a 32 bit integer is plenty big.

fib_array[i] is not initialized when you access it in the while() test. Try changing your while loop to while(true) and using if (fib_array[i]<4000000) break; on the line after you set fib_array[i].
Also, your sum_of_Even is going to need to be a 64 bit integer, so you'll need:
#include <stdint.h>
and then declare it as uint64_t.
Another problem is you aren't declaring how large your fib_array should be, so no actual memory is being allocated to it. Try int fib_array[MAXSIZE]; where MAXSIZE is your calculation for how many entries it will need.

Suggestions on how to fix:
And mindful of #Andrey comment:
"For the record: this is a Project Euler question, and people are strongly discouraged from posting solutions to these online."
Use an array of long long fib_array[3]. To generate Fibonacci numbers only the previous 2 are used to generate the 3rd. After generating a Fibonacci number and testing for evenness, now that you have 3 Fibonacci numbers, discard the eldest and repeat.
OP's present int fib_array[]={}; is not allocating the array needed for OP's approach. fib_array[i]= causes UB.
Per #Jules solution, even a long may be insufficient, consider long long. In anycase , use the matching prinf() format specifier. Edit: Turns out the answer is < 5,000,000, so long will work.
long sum_of_Even = 0;
....
printf("sum of Even terms in the fib sequence = %li\n", sum_of_Even);

#include <stdio.h>
#include <string.h>
int main()
{
long i,s=0,f[50];
f[0]=1;
f[1]=1;
for (i=2;f[i]<4000000;i++){
f[i] = f[i-1] + f[i-2];
if (f[i]%2 == 0){
printf("%ld ",f[i]);
s += f[i];
}
}
printf("SUM = %ld\n",s);
return 0;
}

Related

C - Is there a way to leave a variable unchanged outside of the loop?

I've tried searching for the answer to this question, which is a little tricky when you don't know exactly what you're searching for, but here goes.
I'm making my way through CS50 at the moment (very new at this - I know a bit of HTML/CSS and my day job is in marketing). I'm on the final problem of week 1 - I'm making it tricky for myself by doing the harder problems as well as the easy ones, but I'm keen to learn. So far we haven't talked about arrays, which I suspect might be the answer to this question, but without more knowledge I can't be sure.
I'm working on a credit card validator, where I have to do things like get the length of the card number to validate, add different digits etc. Where I'm struggling, is that if I alter a variable inside a loop in some way, when I go to use that variable again, it has the new value in it - not the original one.
How do I store the original value somewhere so it can be accessed without me having to create dozens of new variables to act as placeholders? (Note - the below is just a tiny snippet of my code as an example - I didn't want to include the whole thing)
e.g.
long long credit; // credit card number
long long len; // used to work out len of card number - feeds into count
// validate length of credit card number and get length of card
len = credit;
while (len > 0)
{
len /= 10;
count ++;
}
In the above example, if I want to use len again further down in my code, it's value will be 0. How do I ensure the original value stays somewhere for me to access in future loops?
I suspect I need to somehow use an array, but so far we've only covered off data types, Booleans, operators, conditional statements and loops (plus printf). All of the info I've found online about arrays talks about needing to specify the array size (the point is I don't know in this example - the values can vary between 13 and 16 digits) and seem more complex than this problem calls for.
I'm pretty sure I'm missing something really simple - I just don't know what it is!
EDIT: Thanks everyone who contributed answers to my very first question! While there may be "better" solutions, it seems that given the constraints I have with my solution specification that I was doing ok and was just overthinking it really. I took the advice from people to copy variables and finally got everything working a few minutes ago.
If anybody would like to see it (although I'm sure my code could do with improvements), my solution is here.
The original specification that I had to meet, was here.
Once again, really appreciated the feedback - I appreciate that this isn't a tutorial site - but sometimes it can be hard to work out what you don't know. Thanks for the help!
You may be looking for the declaration of additional blocks as in
#include<stdio.h>
int main() {
int i=1;
printf("before %d\n",i);
{
int i=0;
printf("within %d\n",i);
}
printf("after %d\n",i);
return(0);
}
which when executed yields
before 1
within 0
after 1
From the comment I grasp that a function invocation may be preferable which may be like
#include<stdio.h>
int div_10_count(long long val) {
int count=0;
while(val>0) {
val /= 10;
count++;
}
return(count);
}
int main() {
long long val=10000000000L;
printf("Before: val=%lld\n",val);
printf("Returned: %d\n",div_10_count(val));
printf("After: val=%lld\n",val);
return(0);
}
shows
Before: val=10000000000
Returned: 11
After: val=10000000000
so the variable val remains unchanged even though the function works with it. This would be different when passing the parameter by reference, i.e. as indicated with the "&".
Whats wrong with using a temporary variable?
You can just make two variables
long long len;
long long lenWork;
len = yourValue;
lenWork = len;
/* Work with lenWork */
lenWork = len;
/* Once again */
lenWork = len;
/* etc... */
You might have forgotten to initialize the count variable to 0.
Use more explicit variable names:
unsigned long long credit; // credit card number
// get length of the credit card number
int count = 0;
for (unsigned long long tmp = credit; tmp > 0; tmp /= 10) {
count++;
}
Here is a more direct method:
if (snprintf(NULL, 0, "%llu", credit) == 16) {
/* credit card number has 16 digits */
}
You could also use a much simpler but less readable method:
if (credit >= 1000000000000000 && credit < 10000000000000000) {
/* credit has 16 digits */
}

Abort trap: 6 (Calculating a long number factorial)

I am following the following function to calculate factorials of big numbers link, and I would like to understand a bit more why some things are happening...
#include<stdio.h>
#define MAX 10000
void factorialof(int);
void multiply(int);
int length = 0;
int fact[MAX];
int main(){
int num;
int i;
printf("Enter any integer number : ");
scanf("%d",&num);
fact[0]=1;
factorialof(num);
printf("Factorial is : ");
for(i=length;i>=0;i--){
printf("%d",fact[i]);
}
return 0;
}
void factorialof(int num){
int i;
for(i=2;i<=num;i++){
multiply(i);
}
}
void multiply(int num){
long i,r=0;
int arr[MAX];
for(i=0;i<=length;i++){
arr[i]=fact[i];
}
for(i=0;i<=length;i++){
fact[i] = (arr[i]*num + r)%10;
r = (arr[i]*num + r)/10;
//printf("%d ",r);
}
if(r!=0){
while(r!=0){
fact[i]=r%10;
r= r/10;
i++;
}
}
length = i-1;
}
My questions are:
What is the real meaning of the MAX constant? What does it mean if it's bigger or smaller?
I have found out that if I have a MAX = 10000 (as in the example), I can calculate up to 3250! If I try with 3251! I get a 'Abort trap: 6' message. Why is that number? Where does it come from?
Which would be the difference if I compile this code for a 32-bit machine with the flag -m32? Would it run he same as in 64-bit?
Thanks!
As Scott Hunter points out, MAX is the maximum number of elements in the fact and arr arrays, which means it's the maximum number of digits that can occur in the result before the program runs out of space.
Note that the code only uses MAX in its array declarations. Nowhere does it use MAX to determine whether or not it's trying to read from or write to memory beyond the end of those arrays. This is a Bad Thing™. Your "Abort trap: 6" error is almost certainly occurring because trying to compute 3251! is doing exactly that: using a too-large index with arr and fact.
To see the number of digits required for a given factorial, you can increase MAX (say, to 20,000) and replace the existing printf calls in main with something like this:
printf("Factorial requires %d digits.\n", length + 1);
Note that I use length + 1 because length isn't the number of digits by itself: rather, it's the index of the array position in fact that contains the most-significant digit of the result. If I try to compute 3251!, the output is:
Factorial requires 10008 digits.
This is eight digits more than you have available in fact with the default MAX value of 10,000. Once the program logic goes beyond the allocated space in the array, its behavior is undefined. You happen to be seeing the error "Abort trap: 6."
Interestingly, here's the output when I try to compute 3250!:
Factorial requires 10005 digits.
That's still too many for the program to behave reliably when MAX is set to 10,000, so the fact that your program calculates 3250! successfully might be surprising, but that's the nature of undefined behavior: maybe your program will produce the correct result, maybe it will crash, maybe it will become self-aware and launch its missiles against the targets in Russia (because it knows that the Russian counterattack will eliminate its enemies over here). Coding like this is not a good idea. If your program requires more space than it has available in order to complete the calculation, it should stop and display an appropriate error message rather than trying to continue what it's doing.
MAX is the number of elements in fact and arr; trying to access an element with an index >= MAX would be bad.
Error messages are often specific to the environment you are using, which you have provided no details for.
They are not the same, but the differences (for example, the size of pointers) should not affect this code in any discernible way.

Why i'm getting runtime error in ideone and codechef compiler and not in my terminal?

I have just started competitive programming in SPOJ.I'm confused from sometime why i'm getting runtime error in ideone.The question is:
A positive integer is called a palindrome if its representation in the decimal system is the same when read from left to right and from right to left. For a given positive integer K of not more than 1000000 digits, write the value of the smallest palindrome larger than K to output. Numbers are always displayed without leading zeros.
Input
The first line contains integer t, the number of test cases. Integers K are given in the next t lines.
Output
For each K, output the smallest palindrome larger than K.
Example
Input:
2
808
2133
Output:
818
2222
My program:
#include <stdio.h>
int main(void)
{
int t,i,reverse,same;
scanf("%d",&t); //t is no. of test cases
int num[t]; //num[t] is array of t elements
for(i=0;i<t;i++)
scanf("%d",&num[i]);
i=0; //since i will be equal to t therefore i is assigned to 0.
while(t--)
{
if(num[i]<=1000000)
{
while(num[i]++)
{
reverse=0;
same=num[i];
while(same>0)
{
reverse=reverse*10;
reverse=reverse+same%10;
same=same/10;
}
if(reverse==num[i])
printf("%d",reverse);
printf("\n");
if(reverse==num[i])
break;
}
}
i++;
}
return 0;
}
I don't know where i'm wrong.I'm sorry i'm asking this question may this question is asked by someone before.I tried to find the result but could not get the answer.Thankyou in advance and sorry for my bad english.
The question doesn't say that the number will be less than 1000000. It says that the number has less than 1 million digits. A number with a million digits looks like this
591875018734106743196734198673419067843196874398674319687431986743918674319867431986743198674319876341987643198764319876341987643198764319876431987643198763419876431987643198764319876139876...
You can't use scanf to read a number that has a million digits, and you can't store that number in an int.
The most likely reason for your error to occur is some memory fault. Keep in mind that online judges/compilers limit your available memory and if you try to allocate/use more memory than available, you get a runtime error. This also happens on your machine, but usually you have a lot more memory available for your program than in the case of online judges.
In your case, you could reduce the memory usage of your program by changing the data type of the num array from int to something like short or even char.

Runtime error while accessing an array for some specific cases

I have the following code to generate prime factors of a number. It is working fine with all the numbers except some. The error I am getting in these numbers is runtime error which is at line 5 and line 10, when trying to access 'factors' array.
and also why is it not giving error when accessing 'factors' array in line 15 and 18.
*This is working perfectly for numbers both greater and lesser than 48598496894, just not for 48598496894.
void getfactors(unsigned long long n){
unsigned long long *factors,i=0,k=0;
//array to store prime factors//
factors=(unsigned long long *)malloc(n*sizeof(unsigned long long));
//getting 2's which are factors of the number//
while(n%2==0){
factors[k++]=2; //line 5
n=n/2;
}
//getting other prime factors of the number//
for(i=3;i<=sqrt(n);i=i+2){
while(n%i==0){
factors[k++]=i; //line 10
n=n/i;
}
}
//last prime factor of number//
if(n>2)
factors[k++]=n; //line 15
printf("%d\n\n",k);
//printing all factors//
for(i=0;i<k;i++)
printf("%llu\n",factors[i]); //line 18
}
int main()
{
getfactors(48598496894);
return 0;
}
You should be checking that factors is not NULL after the malloc in case the allocation fails. You also need to call free to release the memory that you allocated once you're done with it. It would also help if you commented your code to explain your intended behaviour.
To solve your problem I'd recommend checking your array indexing whilst debugging. It might be easier if you used a smaller input value to begin with until you know that your algorithm works.
One other point is whether you need the factors array at all? If the purpose of the function is to print the prime factors, couldn't you just print them as you find them?
Edit
I think #BLUEPIXY has hinted at the issue in the comments. The input argument to malloc is a size_t. On my PC size_t is a 32 bit value. If that's the case on your platform then the size of the block of memory you're trying to allocate is too big. Check if (n*sizeof(unsigned long long)) > SIZE_MAX. As I mentioned earlier, could you just print the factors as you find them and do away with the array?

why runtime error on online judge?

I am unable to understand why i am getting runtime error with this code. Problem is every number >=6 can be represented as sum of two prime numbers.
My code is ...... Thanks in advance problem link is http://poj.org/problem?id=2262
#include "stdio.h"
#include "stdlib.h"
#define N 1000000
int main()
{
long int i,j,k;
long int *cp = malloc(1000000*sizeof(long int));
long int *isprime = malloc(1000000*sizeof(long int));
//long int *isprime;
long int num,flag;
//isprime = malloc(2*sizeof(long int));
for(i=0;i<N;i++)
{
isprime[i]=1;
}
j=0;
for(i=2;i<N;i++)
{
if(isprime[i])
{
cp[j] = i;
j++;
for(k=i*i;k<N;k+=i)
{
isprime[k] = 0;
}
}
}
//for(i=0;i<j;i++)
//{
// printf("%d ",cp[i]);
//}
//printf("\n");
while(1)
{
scanf("%ld",&num);
if(num==0) break;
flag = 0;
for(i=0;i<j&&num>cp[i];i++)
{
//printf("%d ",cp[i]);
if(isprime[num-cp[i]])
{
printf("%ld = %ld + %ld\n",num,cp[i],num-cp[i]);
flag = 1;
break;
}
}
if(flag==0)
{
printf("Goldbach's conjecture is wrong.\n");
}
}
free(cp);
free(isprime);
return 0;
}
Two possibilities immediately spring to mind. The first is that the user input may be failing if whatever test harness is being used does not provide any input. Without knowing more detail on the harness, this is a guess at best.
You could check that by hard-coding a value rather than accepting one from standard input.
The other possibility is the rather large memory allocations being done. It may be that you're in a constrained environment which doesn't allow that.
A simple test for that is to drop the value of N (and, by the way, use it rather than the multiple hardcoded 1000000 figures in your malloc calls). A better way would be to check the return value from malloc to ensure it's not NULL. That should be done anyway.
And, aside from that, you may want to check your Eratosthenes Sieve code. The first item that should be marked non-prime for the prime i is i + i rather than i * i as you have. I think it should be:
for (k = i + i; k < N; k += i)
The mathematical algorithm is actually okay since any multiple of N less than N * N will already have been marked non-prime by virtue of the fact it's a multiple of one of the primes previously checked.
Your problem lies with integer overflow. At the point where N becomes 46_349, N * N is 2_148_229_801 which, if you have a 32-bit two's complement integer (maximum value of 2_147_483_647), will wrap around to -2_146_737_495.
When that happens, the loop keeps going since that negative number is still less than your limit, but using it as an array index is, shall we say, inadvisable :-)
The reason it works with i + i is because your limit is well short of INT_MAX / 2 so no overflow happens there.
If you want to make sure that this won't be a problem if you get up near INT_MAX / 2, you can use something like:
for (k = i + i; (k < N) && (k > i); k += i)
That extra check on k should catch the wraparound event, provided your wrapping follows the "normal" behaviour - technically, I think it's undefined behaviour to wrap but most implementations simply wrap two positives back to a negative due to the two's complement nature. Be aware then that this is actually non-portable, but what that means in practice is that it will only work on 99.999% of machines out there :-)
But, if you're a stickler for portability, there are better ways to prevent overflow in the first place. I won't go into them here but to say they involve subtracting one of the terms being summed from MAX_INT and comparing it to the other term being summed.
The only way I can get this to give an error is if I enter a value greater than 1000000 or less than 1 to the scanf().
Like this:
ubuntu#amrith:/tmp$ ./x
183475666
Segmentation fault (core dumped)
ubuntu#amrith:/tmp$
But the reason for that should be obvious. Other than that, this code looks good.
Just trying to find what went wrong!
If the sizeof(long int) is 4 bytes for the OS that you are using, then it makes this problem.
In the code:
for(k=i*i;k<N;k+=i)
{
isprime[k] = 0;
}
Here, when you do k = i*i, for large values if i, the value of k goes beyond 4 bytesand get truncated which may result in negative numbers and so, the condition k<N is satisfied but with a negative number :). So you get a segmentation fault there.
It's good that you need only i+i, but if you need to increase the limit, take care of this problem.

Resources