Getting a SIGSEGV error on codechef for this code - c

Im trying to submit a solution for the problem FCTRL2(https://www.codechef.com/problems/FCTRL2) on codechef. On executing the code it sometimes gets executed successfully while sometimes it gives a SIGSEGV error. But when I submit it, it always shows wrong answer. Though the code gives correct answer when i run it on any other IDE.
#include <iostream>
#include <stdio.h>
using namespace std;
int main(void)
{
int testCases, i, j, k, n, num, digits, carry = 0, temp;
scanf("%d", &testCases);
int testArr[160];
for (i = 0; i < testCases; i++)
{
scanf("%d", &n);
num = n;
if (n == 0 || n == 1)
{
testArr[0] = 1;
digits = 1;
}
else
{
k = 0;
for (j = 10; n != 0; j = j * 10)
{
testArr[k] = n % j;
n = n / j;
k++;
}
digits = k;
for (j = 1; j < num; j++)
{
for (k = 0; k < digits; k++)
{
temp = testArr[k] * j + carry;
if (temp > 10)
{
testArr[k] = temp % 10;
carry = temp / 10;
}
else
{
testArr[k] = temp;
carry = 0;
}
}
if (carry > 10)
{
testArr[k] = carry % 10;
k++;
testArr[k] = carry / 10;
digits = k + 1;
carry = 0;
}
else if (carry > 0)
{
testArr[k] = carry;
digits = k + 1;
carry = 0;
}
}
}
for (k = (digits - 1); k >= 0; k--)
{
printf("%d", testArr[k]);
}
printf("\n");
}
return 0;
}

Related

Printing prime factors of numbers in C

The code fits the first number and prints it constantly. how can i fix this?
int count = 0;
for (int i = 0; i <= 20; i++) {
for (count = 2; i > 1; count++) {
while (i % count == 0) {
printf("%d ", count);
i = i / count;
}
}
}
The values in each iteration are as follows.
count = 0; i = 0; Doesn't enter the second for.
count = 0; i = 1; Doesn't enter the second for.
count = 0; i = 2; Enters the second for. count = 2;
2 % 2 == 0 - Enters the while.
i = 2 / 2; 1 % 2 == 1; Doesn't enter the while.
Back to the second for - count = 3;, i = 1; Doesn't enter the second for.
Back to the first for - i < 20;, so i = 2.
count = 2; i = 2; and we are back to step 4, with an infinite loop.
This might be what you are looking for -
int j, count = 0;
for (int i = 20; i > 0; i--)
{
printf("\n%d: ", i);
for(count = 2, j = i; j > 1; count++)
{
while(j % count == 0)
{
printf("%d ", count);
j = j / count;
}
}
}
Define a function that checks whether a given number n is prime:
bool is_prime(int n)
{
if (n < 2) return false;
for (int i = 2; i <= n/i; ++i) // Doing i*i<=n may overflow
if (n % i == 0) return false;
return true;
}
And then call it like:
for (int i = 0; i <= 20; i++)
if(is_prime(i))
printf("%d\n", i);
Or more directly (i.e. without a function):
int main(void)
{
int mark;
for (int n = 2; n <= 20; n++) {
mark = 1;
for (int i = 2; i*i <= n; ++i)
if (n % i == 0) mark = 0;
if (mark) printf("%d\n", n);
}
}

Factorial calculation using array

I have a program that calculates the factorial of a number (even over 20), but views the number as a series of digits. In this way:
Here's code:
#include <stdio.h>
#include <stdlib.h>
#define MAXCIF 1000
int main()
{
int f[MAXCIF] = { 1 };
int i, j, n, pom, transmission;
do
{
printf("n="); scanf("%d", &n);
} while (n < 1 || n > 100);
for (i = 2; i <= n; i++)
{
for (j = 0,transmission=0; j < MAXCIF; j++)
{
pom = f[j] * i + transmission;
f[j] = pom % 10;
transmission = pom / 10;
}
}
printf("%d != ", n);
for (j = MAXCIF - 1; f[j] == 0; j--); // It will skip leading zeros
for (; j >= 0; j--)
printf("%d", f[j]); // Prints digits
return 0;
}
What makes me a problem is that I don't understand how these two loops work
for (i = 2; i <= n; i++)
{
for (j = 0,transmission=0; j < MAXCIF; j++)
{
pom = f[j] * i + transmission;
f[j] = pom % 10;
transmission = pom / 10;
}
}
For example, take n = 2:
As I understand these loops, pom = 2, f[0] = 2, transmission = 0.
In the next iteration j = 1, then how is f[1] = 0?
If someone could explain these two for loops, that is, how to manually understand what is happening in them, I would be grateful.

Duplicated output values

I want to display the calendar data in ascending order.
If the date appears several times I need to display it once.
The code works if the date appears five or less times in the input,
if the date appears more than five times at the output it will show up twice.
I don't see the error.
#include <stdio.h>
#include <stdlib.h>
struct date {
int zi;
int luna;
};
int main() {
int n, i, j, k = 0, l;
char c;
scanf("%d", &n);
struct date v[100];
for (i = 0; i < n; i++) {
scanf("%d %c %d", &v[i].zi, &c, &v[i].luna);
}
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (v[i].luna > v[j].luna) {
struct date temp = v[i];
v[i] = v[j];
v[j] = temp;
} else if (v[i].luna == v[j].luna && v[i].zi > v[j].zi) {
struct date temp = v[i];
v[i] = v[j];
v[j] = temp;
}
}
}
printf("\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (v[i].luna == v[j].luna && v[i].zi == v[j].zi && i != j) {
printf("\nOK\n");
for (l = j; l < n - 1; l++) {
// v[l].luna=v[l+1].luna;
// v[l].zi=v[l+1].zi;
v[l] = v[l + 1];
}
n--;
}
}
}
for (i = 0; i < n; i++) {
if (v[i].luna < 10 && v[i].zi >= 10) {
printf("%d-0%d\n", v[i].zi, v[i].luna);
} else if (v[i].zi < 10 && v[i].luna >= 10) {
printf("0%d-%d\n", v[i].zi, v[i].luna);
} else if (v[i].zi < 10 && v[i].luna < 10) {
printf("0%d-0%d\n", v[i].zi, v[i].luna);
} else
printf("%d-%d\n", v[i].zi, v[i].luna);
}
}
The problem seems to be this block:
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (v[i].luna == v[j].luna && v[i].zi == v[j].zi && i != j) {
printf("\nOK\n");
for (l = j; l < n - 1; l++) {
// v[l].luna=v[l+1].luna;
// v[l].zi=v[l+1].zi;
v[l] = v[l + 1];
}
n--;
}
}
}
When you remove a duplicate (i.e. by shifting all elements towards the start and decrementing n) you still increment j. Consequently, your loop will skip one element and you may end up with duplicates.
The solution could be as simple as decrementing j at the same time as you decrement n.
BTW: It seems strange that the j-loop start from zero. I would expect it to start from i+1

Adding two integers (range can be greater than long long int) in C

I wrote the following code to add two integers greater than long long int but somehow it seems that it is entering in an infinite loop.
I am only moderately acquainted with the language so the code is a bit clumsy. It will be great if someone points out my mistake.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char a[127], c[127];
char b[127], d[127];
char result[127];
int i, j, k, l1, l2, sum, carry;
printf("\n\nenter 1st number\n\n");
gets(a);
printf("\n\nenter 2nd number\n\n");
gets(b);
l1 = strlen(a);
l2 = strlen(b);
// for(i=0;i<=l1;i++)
// printf("%c",a[i]);
j = l1;
k = l2;
/*for(i=l1;i>=0;i--)
{
c[j]=a[i];
j--;
}
for(i=l2;i>=0;i--)
{
d[j]=b[i];
j--;
}*/
printf("\n%d %d\n", j, k);
if (l1>l2)
{
for (i = l1; i <= l2; i--)
{
c[i] = a[j];
d[i] = b[k];
j--;
k--;
}
for (i = l2; i <= 0; i--)
{
c[i] = a[j];
d[i] = 0;
j--;
}
}
// printf("hello");
j = l1;
k = l2;
if (l1<l2)
{
for (i = l2; i <= l1; i--)
{
c[i] = a[j];
d[i] = b[k];
j--;
k--;
}
for (i = l1; i <= 0; i--)
{
c[i] = 0;
d[i] = b[k];
k--;
}
}
j = l1;
k = l2;
if (l1 = l2)
{
for (i = l2; i <= 0; i--)
{
c[i] = a[j];
d[i] = b[k];
j--;
k--;
}
}
if (l1>l2)
{
for (i = l1; i <= 0; i--)
printf("%c", c[i]);
}
if (l1>l2)
{
for (i = l1; i >= 0; i--)
{
if (i = l1)
carry = 0;
else
/*if(i=l2)
carry[i]=0;
else
carry[i]=sum[i]*/
carry = sum / 10;
sum = ((c[i] - '0') + (d[i] - '0')) + carry;
// if(i!=0)
result[i] = sum % 10 + '0';
// else
// result[i]=sum[i];
}
// for(i=l1-l2;i<=l1;i++)
// result[i]=c[i];
}
if (l1<l2)
{
for (i = l2; i >= 0; i--)
{
if (i = l2)
carry = 0;
else
carry = sum / 10;
sum = (c[i] - '0') + (d[i] - '0') + carry;
//if(i!=0)
result[i] = sum % 10 + '0';
// else
// result[i]=sum[i];
}
// for(i=l2-l1;i<=l2;i++)
// result[i]=d[i];
}
if (l1 = l2)
{
for (i = l1; i >= 0; i--)
{
if (i = l1)
carry = 0;
else
carry = sum / 10;
sum = (c[i] - '0') + (d[i] - '0') + carry;
if (i != 0)
result[i] = sum % 10 + '0';
else
result[i] = sum + '0';
}
}
printf("\n\nthe result is\n\n");
if (l1 >= l2)
{
for (i = 0; i <= l1; i++)
printf("%c", result[i]);
}
else
{
for (i = 0; i <= l2; i++)
printf("%c", result[i]);
}
printf("\n\n");
return 0;
}
First off, you should never use gets because you cannot specify how many characters it should read; it may very well overflow your buffer. Instead, use fgets(buf, sizeof(buf), stdin).
The reason why your code is looping forever is all your ifs are wrong - you're using the assignment operator = instead of the comparison operator ==. = returns the assigned value, i.e. if (var = 0) always returns 0, which means the code inside that if will never be executed. When you fix all your if statements, you'll discover the next problem:

I cannot find memory leak. (SIGSEGV) (segmented sieve of Eratosthenes) (C)

I'm trying to implement segmented sieve of Eratosthenes in C (im beginner programmer) and it just prints proper output but I'm getting SIGSEGV when I'm submitting in on SPOJ. Can you help me spot the leak?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void segmented_sieve(int *m, int *n, int t) {
int count, i, j, l, sqrt_imax, hlp_imin;
count = i = j = l = sqrt_imax = hlp_imin = 0;
int *imin, *imax;
imin = m;
imax = n;
sqrt_imax = (int)sqrt((double)imax[t]);
int *sieve;
sieve = malloc((imax[t] + 1) * sizeof(*sieve));
memset(sieve, 1, (imax[t] + 1) * sizeof(*sieve));
for (i = 2; i <= sqrt_imax; ++i) {
for (j = i * i; j <= imax[t]; j += i)
sieve[j] = 0;
}
int *next;
next = malloc((int)sqrt(1000000000) * sizeof(*next));
for (i = 2; i <= sqrt_imax; ++i) {
if (sieve[i] > 0) {
++count;
next[count] = i;
}
}
for (i = 1; i <= count; ++i) {
if (imin[t] <= 2) {
imin[t] = 2;
for (j = next[i]; j <= sqrt_imax; j = next[i]) {
for (l = j * j; l <= n[t]; l += j)
sieve[l] = 0;
break;
}
}
else {
hlp_imin = (int)(m[t] / next[i]);
hlp_imin *= next[i];
for (j = next[i]; j <= sqrt_imax; j = next[i]) {
for (l = hlp_imin; l <= imax[t]; l += j)
sieve[l] = 0;
break;
}
}
}
for (i = imin[t]; i < imax[t]; ++i)
sieve[i] > 0 ? printf("%d\n", i) : 0;
free(sieve);
free(next);
}
int main()
{
int t, tmp, i;
t = tmp = i = 0;
scanf("%d", &t);
int *m;
m = malloc(t * sizeof(*m));
int *n;
n = malloc(t * sizeof(*n));
for (i = 0; i < t; ++i) {
scanf("%d", &tmp);
m[i] = tmp;
scanf("%d", &tmp);
n[i] = tmp;
}
for (i = 0; i < t; ++i) {
segmented_sieve(m, n, i);
printf("\n");
}
free(m);
free(n);
return 0;
}
I fixed it by changing int to char. now just getting TLE...
Think about what happens if you get two values imin = 2,000,000,000 and imax = 2,000,000,010. You should create a tiny sieve for just 11 numbers. But you allocate storage for 2 billion ints which is probably more than your computer can handle.

Resources