SIGSEGV error on SPOJ - c

I would like to solve problem PRIME1 on SPOJ. When I run Code Blocks and input test examples, I get correct answer. But when I submit my code to SPOj, I get SIGSEGV error. Here is the explanation of this error on SPOJ:
SIGSEGV (signal 11) - the most common error for non-interpreted languages: a "segmentation fault" of the program. This may be caused e.g. by an out-of-scope array index causing a buffer overflow, an incorrectly initialized pointer, etc.
But I can't find this type of problem in my code. Could anyone help me, please?
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <math.h>
int prim(int n)
{
int s, i;
if (n == 1 || n == 2)
return 1;
if (n % 2 == 0)
return 0;
s = (int)sqrt(n);
for (i=3; i<=s; i+=2)
if (n % i == 0)
return 0;
return 1;
}
void print(int a,int b)
{
int *p,i,k;
int g;
g=(b/2);
p = (int *) malloc (sizeof(int)*(b-a+1));
for(i=0;i<(b-a+1);i++) p[i]=a+i;
for(i=0;i<=g;i++)
{
if(p[i] && prim(p[i]))
{
for(k=i*2+a;k<b-a;k+=i+a)
p[k]=0;
}
if(!prim(p[i]))
{
p[i]=0;
for(k=i*2+a;k<=b-a;k+=i+a)
p[k]=0;
}
}
for(i=0;i<(b-a+1);i++) if(p[i]!=0) printf("%d ",p[i]);
free(p);
}
int main(void)
{
int t,i,m,n;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d %d",&m,&n);
print(m,n);
}
return 0;
}

The problem is that g maybe greater than or equal to (b-a+1), depending on the test case. Since g = b/2 then for the array index i to not go out of bounds, b/2 < b-a+1 which implies that b/2 > a-1. That is not necessary. Since a can be say 6 and b can be like 7 according to the problem constraints.
Also according to the constraints, your code might well give TLE. Your algorithm is currently in the worst case O((n-m)*sqrt(n)), which I think is not enough to get AC in this question.
Read about Sieve of Eratosthenes and try to use it to solve this.

Related

Why is my factorial program using recursion not working

I am new to coding. so I wanted to write a c program using recursion to calculate the factorial of a number.
#include <stdio.h>
int fact(int a) {
int n = 1;
if (a != 0)
return;
else
n = n * a;
a--;
fact(a);
return n;
}
int main() {
printf("%d", fact(5));
return 0;
}
This is the program I have written. I know this is probably wrong but I think I would understand programming better if I was able to understand why the above program is exactly wrong.
Because whenever you pass any value other than 0 to fact your code exits without even returning a value:
if(a!=0)
return;
You should get at least a warning from your compiler that this is invalid code, since fact is expected to always return an int value.
But even more so, this is a logical error.
Did you mean to write:
if (a == 0) return 1; //0! = 1
Lev M. pointed out your mistakes in his answer. This is a working recursive implementation of the factorial algorithm.
unsigned int fac(unsigned char n)
{
if (n == 0)
return 1;
return n * fac(n - 1);
}

Large array causing segmentation fault

I wrote a code with the following specified constraints:
Hence I chose the data types for my variables accordingly.
However my code fails all the test cases saying segmentation fault. (possibly because the array size they input is very large.) Is there a way to get more stack space or heap space? or get around this problem by declaring the array in some other way? Is there something else that's causing segmentation fault? Other people have solved this problem, so there must be a way.
this is the code:
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
long find_index(long x, long *cost, long n, long used_index)
{
long i;
for(i = 0; i < n; i++)
if(*(cost + i) == x && i != used_index)
return (i+1);
return 0;
}
int purchase(long *cost, long n, long money)
{
long i, index;
for(i = 0; i < n ;i++)
{
index = find_index((money - *(cost - i)),cost,n,i);
if(index)
{
printf("%ld %ld\n",i+1,index);
break;
}
}
free(cost);
return 0;
}
int main(void)
{
int t;
long *cost, money, n, i;
scanf("%d",&t);
while(t > 0)
{
scanf("%ld",&money);
scanf("%ld",&n);
cost = (long *)malloc(n*sizeof(long));
for(i = 0; i < n; i++)
scanf("%ld",(cost+i));
purchase(cost,n,money);
t--;
}
return 0;
}
this is one of the hidden test cases they check for:
35 // this is t
299701136 // this is money
2044 // this is n
50293811 136626876 58515785 59281065 ..... goes on forever...
That's a lot of complex code to analyze, so instead of giving you a fish, I'll try to give you a rod.
Whatever platform, compiler and IDE you're using, there probably is a way to perform step-by-step debugging of your program at runtime. Maybe your assumptions are wrong and the allocation size is not causing this problem.
Learning basics of debugging is really great tool in programmer's hands. Here is an example tutorial video: https://www.youtube.com/watch?v=9gAjIQc4bPU
These changes in the code fix the issue of array index out of bounds problem, Hence the segmentation fault issue:
if((money - *(cost + i)) < n)
index = find_index((money - *(cost + i)),cost,n,i);
The constraints mentioned cause no issue.

Reverse two numbers and obtain the reverse of the sum

I am coming to SO as a last resort. Been trying to debug this code for the past 2 hours. If the question is suited to some other SE site, please do tell me before downvoting.
Here it goes:
#include <stdio.h>
#include<math.h>
int reverse(int n) {
int count = 0, r, i;
int k = (int)log(n * 1.0);
for(i = k; i >= 0; i--)
{
r = (n % 10);
n = (n / 10);
count = count + (r * pow(10, k));
}
return count;
}
int main(void) {
int t;
scanf("%d", &t);
while(t--)
{
int m, n, res;
scanf("%d %d", &m, &n);
res = reverse(m) + reverse(n);
printf("%d", reverse(res));
}
return 0;
}
My objective is to get 2 numbers as input, reverse them, add the reversed numbers and then reverse the resultant as well.I have to do this for 't' test cases.
The problem: http://www.spoj.com/problems/ADDREV/
Any questions, if the code is unclear, please ask me in the comments.
Thank you.
EDIT:
The program gets compiled successfully.
I am getting a vague output everytime.
suppose the 2 numbers as input are 24 and 1, I get an output of 699998.
If I try 21 and 1, I get 399998.
Okay, if you had properly debugged your code you would have notices strange values of k. This is because you use log which
Computes the natural (base e) logarithm of arg.
(took from linked reference, emphasis mine).
So as you are trying to obtain the 'length' of the number you should use log10 or a convertion (look at wiki about change of base for logarithms) like this: log(x)/log(10) which equal to log10(x)
And now let's look here: pow(10, k) <-- you always compute 10^k but you need 10^i, so it should be pow(10, i) instead.
Edit 1: Thanks to #DavidBowling for pointing out a bug with negative numbers.
I don't know how exactly you have to deal with negative numbers but here's one of possible solutions:
before computing k:
bool isNegative = n < 0;
n = abs(n);
Now your n is positive due to abs() returning absolute value. Go on with the same way.
After for loop let's see if n was negative and change count accordingly:
if (isNegative)
{
count = -count;
}
return count;
Note: Using this solution we reverse the number itself and leave the sign as it is.
It looks like Yuri already found your problem, but might I suggest a shorter version of your program? It avoids using stuff like log which might be desirable.
#include <stdio.h>
int rev (int n) {
int r = 0;
do {
r *= 10;
r += n % 10;
} while (n /= 10);
return r;
}
int main (void) {
int i,a,b;
scanf("%d",&i);
while (i--) {
scanf("%d %d",&a,&b);
printf("%d\n",rev(rev(a) + rev(b)));
}
return 0;
}
Hopefully you can find something useful to borrow! It seems to work okay for negative numbers too.
Under the hood you get char string, reverse it to numeric, than reverse it to char. Since is more comfortable work with chars than let's char:
char * reverse (char *s,size_t len) //carefull it does it in place
{
if (!len) return s;
char swp, *end=s+len-1;
while(s<end)
{
swp =*s;
*s++=*end;
*end--=swp;
}
return s;
}
void get_num(char *curs)
{
char c;
while((c=getchar())!='\n')
*curs++=c;
*curs=0;
}
int main()
{
double a,b,res;
char sa[20],sb[20],sres[20],*curs;
get_num( sa);
get_num(sb);
reverse(sa,strlen(sa));
reverse(sb,strlen(sb));
sscanf(sa,"%f",&a);
sscanf(sb,"%f",&b);
res=a+b;
sprintf(sres,"%f",res);
reverse(sres);
printf(sres);
}

Recursion - math formula, write a program

I need to implement this math formula in C:
I wrote a code:
#include <stdio.h>
int c(int n, int k)
{
if(k == 0)
return n;
if(c(n,k-1) % 2 == 0)
return c(n,k-1)/2;
if(c(n,k-1) % 2 != 0)
return c(n,k-1) * 3 + 1;
}
int main()
{
printf("%d", c(3,8));
return 0;
}
But I'm wondering if it was all about it? Does it work like it should? I must admit I have some troubles with calculating it on a paper ...
According to my calculation, the correct answer for n=3, k=8 should be 4, so your example should give you that. The program itself looks correct.
Update:
Here is how I do it on paper:
We're starting from c(0) - since in this case the value is known in any case:
c(0)=n=3
And go up, on each step choosing the calculation method based on evenness of the c(k-1):
c(1)=c(0)*3+1=10
c(2)=c(1)/2=5
c(3)=c(2)*3+1=16
c(4)=c(3)/2=8
c(5)=c(4)/2=4
c(6)=c(5)/2=2
c(7)=c(6)/2=1
c(8)=c(7)*3+1=4

UVa 3n+1 Case Recursive Stack Overflow

im trying to solve this very first challange but i get stuck,
i like fast program, so i decided to use recursive method not iteration
unfortunately, when the input is a big integer (100000 > input > 1000000), its often crash
so i debug it, and it shows stack overflow error
please help me, i dont know what to do, ive tried to change data type to unsigned long, unsigned int, etc, but none of it works
here is my code,
im using ANSI C
#include "stdio.h"
int cek(int n) {
return n % 2;
}
int fung(int n,int c) {
if (n == 1) {
return c;
}
if (!cek(n)) {
return fung(n/2,++c);
}
else {
return fung((n*3)+1,++c);
}
}
int comp(int i,int j,int tmp) {
int temp;
if (i == j)
return tmp;
temp = fung(i,1);
if (temp > tmp)
return comp(++i,j,temp);
else
return comp(++i,j,tmp);
}
int main() {
int i,j,tmp;
while (scanf("%d %d",&i,&j)) {
if (i > j) {
tmp = i;
i = j;
j = tmp;
}
printf("%d %d %d\n",i,j,comp(i,j,0));
}
return 0;
}
PS: sorry for my stupidness, im really a newbie #_#
Recursion is not likely to be faster than iteration, and in fact it's likely to be slower.
The call stack has a limited size, and if your recursion goes deeper than that, there's nothing you can do about it. Especially in the Collatz problem, there's no way to tell up front how many steps you'll need. Rewrite this using an iterative method instead.
(If your compiler does tail call optimization, recursion might still work. But TCO is not required by the standard, so it will lead to unportable code. And apparently, your compiler does not optimize this particular tail call anyway.)
Not a C expert, but usually there is a call stack depth limit enforced by the compiler. Probably you can change this with a compiler flag, but this will not solve your problem. Making the algorithm iterative instead of recursive will fix it.
Recursive algorithms won't go faster than iterative ones, usually. But they are typically nicer to understand. (= more elegant)
Okay guys,
i found it!!!
so this is my code, i still use recursion but only for the inner loop fung(),
im not really impressed of it, because its need 0,5 sec to count input 1 and 1000000, someone's code outhere can do it in 0 sec, LOL
i change the outer loop comp() with iterative method,
look here
#include "stdio.h"
/*#include "windows.h"*/
int cek(int n) {
return n % 2;
}
unsigned int fung(unsigned int n,unsigned int c) {
if (n == 1) return c;
if (!cek(n)) return fung(n/2,++c);
else return fung((n*3)+1,++c);
}
/*
Above recursion will looked like this in iterative method
int func(int n) {
int c=1;
while (n != 1) {
c++;
if (n % 2 == 0)
n=n/2;
else
n=(n*3)+1;
}
return c;
}
*/
/*Outer Loop*/
int iter(int i,int j) {
int tmp1=0,tmp2;
while (i <= j) {
tmp2 = fung(i,1);
if (tmp1 < tmp2)
tmp1 = tmp2;
i++;
}
return tmp1;
}
int main() {
unsigned int i,j,s,f;
while (scanf("%d %d",&i,&j)) { /*UVa Standard, infinite loop*/
/*s = GetTickCount();*/
printf("%d %d %d",i,j,iter(i,j));
/*f = GetTickCount();
printf("%lu\n",f-s);*/
}
return 0;
}

Resources