Project Euler number 37 - c

Here's the problem statement:
The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
My code gives me a partial output. Only 5 or 6 of the eleven required primes are being outputted, 3797 not being one of them. So to find the error, I manually (on a piece of paper) ran the code for 3797 and somehow can't manage to find the glitch.
I think the error is in the second part, the part of code which checks whether the number is truncatable from the left.
Code:
#include<stdio.h>
int isprime(int n) //Checks whether the number is prime or not
{
int i;
if(n==1)
return(0);
for(i=2;i<n/2+1;i++)
{
if(n%i==0)
{
return(0);
break;
}
}
return(1);
}
int main(void)
{
int count=0,z=0;
int i;
int n;
int x=1;
int reverse2=0;
int z1=0;
int p;
int count1=0;
int digit;
int k=1000000;
int reverse=0;
for(i=2;i<k;i++)
{
if(isprime(i)==1)
{
n=i;
p=i;
while(n>0) // This function removes the digits of the prime number from the right
{
n=n/10;
if(isprime(n)==1)
{
count++;
}
z++;
}
if(z==count)
{
while(p>0) //Checks whether number is left truncatable
{
digit=p%10;
p=p/10;
if(z1==0)
{
reverse=digit;//here reverse doesn't refer to reversing the number. It builds the number one digit at a time from right to left.
}
else
{
reverse=digit*x*10+reverse;
x++;
}
if(isprime(reverse)==1)
{
count1++;
}
z1++;
}
if(z1==count1)
printf("%d ",i);
}
z=0;
z1=0;
count1=0;
count=0;
reverse=0;
reverse2=0;
x=1;
}
}
}

Your left truncatable check is wrong. I did it differently, simpler.
#include<stdio.h>
int isprime(int n) //Checks whether the number is prime or not
{
int i;
if(n==1)
return(0);
for(i=2;i<n/2+1;i++)
{
if(n%i==0)
{
return(0);
break;
}
}
return(1);
}
int power(int a, int b){
int r = 1;
int i=0;
for (i=0;i<b;i++){
r = r * a;
}
return r;
}
int main(void)
{
int count=0,z=0;
int i;
int n;
int z1=0;
int p;
int count1=0;
int digits;
int k=1000000;
for(i=2;i<k;i++)
{
if(isprime(i)==1)
{
z = 0;
count = 0;
n=i;
p=i;
while(n>0) // This function removes the digits of the prime number from the right
{
n=n/10;
if(isprime(n)==1)
{
count++;
}else{
count = -1;
break;
}
z++;
}
if(z==count)
{
z1= 0;
count1=0;
n = i;
p= i;
while(p>0) //Checks whether number is left truncatable
{
digits=n%power(10,z1+1);
p = p /10;
if (isprime(digits)==1)
{
count1++;
}else{
count1 =-1;
break;
}
z1++;
}
if(z1==count1)
printf("%d\n ",i);
}
}
}
}

Related

Displaying perfect numbers and their adders

I need help with the program to display first 4 perfect numbers in the standard output and also funciton perfect(int,int*). Arguments of this function are natural number and the adress where you neeed to write the adders (of the perfect number I suppose). Function has to return 1 if the number is perfect, and 0 if it's not. This is what I've done so far. Help please.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int perfect(int,int*);
int main()
{
int *arr,a;
int i,j;
perfect(a,arr);
}
int perfect(int n,int *arr)
{
int lim=8128,i,sum;
for(n=1;n<=lim;n++)
{
sum=0;
for(i=1;i<n;i++)
{
if(n%i==0)
{
sum=sum+i;
}
}
if(n==sum)
printf("%d ",n);
}
}
I think this code is helpful for you. The perfect function returns 1 when perfect otherwise return 0. The global array divisor which is used for collecting the addr. When the perfect function returns 1 then I print the divisor array and initiate the deivisor_count =0. Please have a look:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int divisor[1000], deivisor_count = 0;
int perfect(int n)
{
int sum=0, i, j = 0;
for(i=1;i<n;i++)
{
if(n%i==0)
{
sum=sum+i;
divisor[deivisor_count]= i;
deivisor_count = deivisor_count + 1;
}
}
if(n==sum){
return 1;
}
return 0;
}
int main()
{
int i, j =0, is_perfact, n=100000, k;
for (i =2 ; i<=n; i++){
deivisor_count = 0;
is_perfact = perfect(i);
if(is_perfact == 1){
j = j + 1;
for(k = 0; k <deivisor_count; k++){
printf("%d", divisor[k]);
if (deivisor_count -1 == k){
printf("=");
}
else{
printf("+");
}
}
printf("%d\n", i);
}
if (j==4){
break;
}
}
return 0;
}

Twin primes C code

I'm trying to print the following series 4 6 12 18 30 42 60 72....up to n in C language. Its logic is simple; we have to print the number such that the preceding and successive number should be prime! But the following code is not looping after printing the 4. What's wrong in the following code?
#include <stdio.h>
int main(){
int n, i, j, p2, k;
int count1=0, count2=0;
printf("enter the number:\n");
scanf("%d",&n);
for(i=3;i<n;i++){
for(j=2;j<i;j++){
if(i%j==0){
count1++;
break;
}
}
p2=i+2;
for(k=2;k<i;k++){
if(p2%k==0){
count2++;
break;
}
}
if(count1==0 && count2==0){
printf("%d",i+1);
}
}
}
You just need to set counters to 0 at the end of the loop
#include<stdio.h>
int main(){
int n, i, j, p2, k;
int count1=0, count2=0;
printf("enter the number:\n");
scanf("%d",&n);
for(i=3;i<n;i++){
for(j=2;j<i;j++){
if(i%j==0){
count1++;
break;
}
}
p2=i+2;
for(k=2;k<i;k++){
if(p2%k==0){
count2++;
break;
}
}
if(count1==0 && count2==0){
printf("%d ",i+1);
}
count1=0; count2=0;
}
}
your code is right, just set count1 and count2 to 0 at the end of the outer for loop.
you can try it this way too.
this code is in Java. you can convert it to C . Logic remains the same.
for Arraylist take arrays of fixed length equal to n.
import java.util.*;
class prime
{
public static void main(String[] args){
int n, i, j, p2, k,o;
ArrayList<Integer> prime = new ArrayList<Integer>();
ArrayList<Integer> series = new ArrayList<Integer>();
int count1=0, count2=0;
Scanner s = new Scanner(System.in);
System.out.println("enter the number:\n");
n=s.nextInt();
if(n<3)
{
System.out.println("prime numbers start from 3");
}
for(i=3;i<=n;i++)
{
for(j=2;j<i;j++)
{
if(i%j==0)
{
count1=1;
break;
}
}
if(count1==0)
{
prime.add(i);
}
count1=0;
}
for(k=0;k<prime.size()-1;k++)
{
int prdsr=prime.get(k);
int sucsr=prime.get(k+1);
if((sucsr-prdsr)==2)
{
series.add((prdsr+1));
}
}
for(o=0;o<series.size();o++)
{
System.out.print(" "+series.get(o));
}
}
}

Why this program is having Segmentation fault (core dumped) in line 62: 13

Problem statement:
Given N sticks each of different integral length Li, find the probability that you can make a quadrilateral taking 4 sticks at random (not paying attention to the order) from the given N sticks. (Degenerate quadrilaterals not included.)
Constraints:
1 <= M<=10
3 <= N <= 1000
1 < = Li < = 1500
Code:
#include<stdio.h>
int gcd(int n1,int n2) // calculate GCD
{
if(n1==0||n2==0) return 0;
if(n1==n2) return n1;
if(n1>n2) return gcd(n1-n2,n2);
return gcd(n1,n2-n1);
}
int main(void)
{
int m; // test cases
scanf("%d",&m);
while(m--)
{
int n;
scanf("%d",&n);
int a[1501];
int b[n];
int i,val,k;
for(i=1;i<=1500;i++) a[i]=0; //initialization
for(i=0;i<n;i++) //taking values
{
scanf("%d",&val);
a[val]=1;
}
int j=0,l,tcase=0,fcase=0; //truecase and falsecase
for(i=1;i<=1500;i++) //making another array of length n
{
if(a[i]==1)
{
b[j]=i;
j++;
}
}
if(n<4) printf("0/1\n");
else
{
for(i=0;i<=n-4;i++)
{
for(j=i+1;j<=n-3;j++)
{
for(k=j+1;k<=n-2;k++)
{
for(l=k+1;l<=n-1;l++)
{
if((b[i]+b[j]+b[k])>b[l]) tcase++;
else
{
fcase=fcase+(n-l);
l=n;
}
} //line: 62
}
}
}
int ttcase=tcase+fcase; //total possible cases
int div=gcd(tcase,ttcase); //to make a/b form
if(div==0) printf("0/1\n");
else
{
tcase=tcase/div; //to make a/b form
ttcase=ttcase/div; //to make a/b form
printf("%d/%d\n",tcase,ttcase);
}
}
}
return 0;
}

Finding next smallest palindrome, infinite loop

I am writing a code to find the next smallest palindrome(integer) . I am (must) using array to deal with too large numbers like below:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
void check_pal(int a[],int max)
{
int i,j,ctr,k;
while(1)
{
for(i=0;i<max;i++)
printf("%d",a[i]);
ctr=0;
k=max-1;
while(a[k]==9)
{
a[k--]=0;//add corner case when k==0
}
a[k]++;
for(i=0,j=max;i<max/2;i++,j--)
{
printf("%d",i);
if(a[i]!=a[j])
{
ctr=1;
break;
}
}
if(ctr==0)
for(i=0;i<max;i++)
{
printf("%d",a[i]);
if(i==max-1)
return;
}
}
}
void int_convert(char * m,int a[] )
{
int i,max;
for(i=0;i<strlen(m);i++)
{
// printf("%c",m[i]);
a[i]=m[i]-'0';
}
max=strlen( m);
printf("%d\n",max);
check_pal(a,max);
}
void main()
{ int a[200],max;
char * m=malloc(sizeof(char)*200);
scanf("%s",m);
int_convert(m,a);
getch();
}
The output result is an infinite loop .
For e.g. for input 45 the output must be 55 but it is resulting in 0000000 ..
Please tell me where I am wrong .
It is not difficult to recognize palindromes:
int is_palindrome(int a[], int max) {
for (int i = 0; i < max/2; i++) {
if (a[i] != a[max-i-1]) {
return 0;
}
}
return 1;
}
It is not difficult to increment the value:
void next_value(int a[], int max) {
int i = max - 1;
a[i]++;
while (i > 0 && a[i] > 9) {
a[i] = 0;
a[i-1]++;
i--;
}
}
It's easy to display the value:
void show(int a[], int max) {
for (int i = 0; i < max; i++) {
printf("%d", a[i]);
}
printf("\n");
}
With this support it's trivial to find the smallest following palindrome:
void check_pal(int a[], int max) {
while (!is_palindrome(a, max)) {
next_value(a, max);
}
show(a, max);
}
By the way, I would call the function find_pal rather than check_pal.

Pascals Triangle

I was trying to print Pascal's Triangle using the following code. But after printing the first '1' the compiler runs into an error and I have to manually stop the execution. What might be the error in the code?
EDIT: fact function has been changed as shown with no difference whatsoever.
I'm using Codeblocks 10.05. A dialog window pops up and says that .exe has stopped working and Windows is searching for a solution.
#include <stdio.h>
void comb(int,int);
int fact(int);
int main()
{
int n,row;
scanf("%d",&n);
int j,k;
for(row=1;row<=n;row++)
{
for(j=0;j<n-row;j++)
{
printf(" ");
}
for (k=0;k<2*row-1;k++)
{
comb(row-1,k);
}
printf("\n");
}
return 0;
}
void comb(int a,int b)
{
if(a==0)
printf("%d",1);
printf("%d",fact(a)/(fact(a-b)*fact(b)));
}
int fact(int num)
{
if(num == 1)
{
return 1;
}
else return num*fact(num-1);
}
Your problem is that fact(0) will go into an infinite loop calling fact(-1), then fact(-2), and so on. Eventually it'll crash due to recursion running out of stack space.
How does fact(0) happen? when fact(a-b) is called when a == b.
This currently happens when row == 2, k == 1.
There are two mistakes that I can see
fact function: it's infinitely recursive
improper bounds of loop which calls comb function. There are row + 1 elements in each row, not 2 * row - 1. your formula works only for the first two rows.
Try this code
#include <stdio.h>
void comb(int,int);
int fact(int);
int main()
{
int n;
printf("Height: ");
scanf("%d",&n);
for(int row = 1; row <= n; row++)
{
if( row == 1)
printf(" ");
for(int j = 0;j < n - row; j++)
{
printf(" ");
}
for (int k = 0;k < row + 1;k++)
{
if ( row != 1)
comb(row,k);
else
{
printf("1");
break;
}
}
printf("\n");
}
return 0;
}
void comb(int a,int b)
{
printf("%d ",fact(a)/(fact(a-b)*fact(b)));
}
int fact(int num)
{
if(num > 1)
return num * fact(num-1);
else
return 1;
}
int main(){
int n,row;
scanf("%d",&n);
int j,k;
for(row=1;row<=n;row++)
{
for(j=0;j<n-row;j++)
{
printf(" ");
}
for (k=0;k<=row-1;k++)
{
comb(row-1,k);
}
printf("\n");
}
return 0;
}
void comb(int a,int b){
printf("%d",fact(a)/(fact(a-b)*fact(b)));
}
int fact(int num){
if(num < 2)
return 1;
else
return num*fact(num-1);
}

Resources