Finding the n-th prime number that is palindrome in base K - c

I recently asked a question about finding whether a number is palindrome in base K or not and I get my answer.
My Recent Question
Now I have a more complicated question, We will get two numbers n and k, and we must find the n-th prime number that is palindrome in base K.
For example if we get 8 and 10, we have 2 3 5 7 11 101 131 151 which are palindrome and prime and so the answer is 151. Another example is 4 2 we have 3 5 7 17 respectively 11 101 111 10001 in base 2 which are prime and palindrome in base so the answer is 17.
n and k are given such that the answer is at most, 1E7.
I submit my program in a judge system and It gave wrong answer in some cases and also Time Limit error in one case. I don't know which part of my algorithm is wrong and what part of it is not optimised.
Note that I am not allowed to use array,vector and strings and also I cannot use libraries more than stdio.h and math.h. It is my program, Can anyone find any problems in it: (I defined intPow because the pow function in math, gives a float and sometime it causes problems)
#include <stdio.h>
#include <math.h>
int primeCheck ( int n);
int palindrome ( int n,int base);
int digitCountBase (int n , int base);
int intPow (int a , int b);
int main()
{
int n;
int base;
scanf("%d %d",&n,&base);
int counter = 0;
int i =2;
int firstRound =1;
while (counter!=n)
{
if (primeCheck(i))
{
if (palindrome (i,base))
{
counter++;
}
}
if (counter ==n)
{
break;
}
if (firstRound)
{
i++;
firstRound=0;
}
else{i+=2;}
}
printf("%d",i);
return 0;
}
int primeCheck ( int n)
{
if (n<2)
{
return 0;
}
if (n==4)
{
return 0;
}
else if (n<=5)
{
return 1;
}
if (n%2 ==0 || n%3 ==0 || n% 5 ==0)
{
return 0;
}
int i =5;
int limit = sqrt(n)+2;
for (int i =5;i<=limit;i+=6)
{
if (n%i==0||n%(i+2)==0)
{
return 0;
}
}
return 1;
}
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
while (n>0&& digitCount >0)
{
if (n%base != (n/power)&&digitCount!=1)
{
isTrue =0;
return 0;
}
n = n- power;
n=n/base;
power = power /base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
int digitCountBase (int n , int base)
{
int digits=0;
while (n)
{
digits++;
n = n / base;
}
return digits;
}
int intPow (int a , int b)
{
int result = 1;
for (int i=1;i<=b;i++)
{
result = result * a;
}
return result;
}

Solution: change palindrome to
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
int original = n;
while (n>0&& digitCount >0)
{
if (n%base != (original/power) % base &&digitCount!=1)
{
isTrue =0;
return 0;
}
n=n/base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
How did I find the error:
You are doing only 2 things, primality testing and palindrome testing, so makes sense to check if these are working fine.
Primality testing is easy, count primes from 1 to 10^7 and compare to known values on google. In this case, this works
To test palindrome, pick a working solution from the internet (even if you can´t submit their solution that uses arrays/strings, you can test with them!). Then iterate from 1 to 10^7 in a certain base and check that both functions return the same.
Testing with base 3, quickly saw that 56 was not giving same output. And the incorrect one was yours.
Then its a matter of fixing your function, which you now know which one is the problem and even have an example of where its not working

Related

Next Prime number function problem when I use a recursive function

I have a problem with a recursive function. The function must return the next prime number.
As parameter I give a number an it must return the number if is prime, or the next prime number.
The function works fine in almost cases, when I comment the recursion it shows a list of numbers from one to hundred and allocate the primes. The rest return O.
But when I insert the recursive in some cases shows a next prime that is not prime, case of 35 and 95 for example.
when I put 4 it show the next prime that is 7.
but when it reaches 32 it shows 35 that was not correct. It should shows 37.
I don't know were the problem is.
The code is:
#include <stdio.h>
#include <unistd.h>
int ft_find_next_prime(int nb)
{
int i;
int z;
i = nb - 1;
z = nb;
while (i > 1)
{
if ((z % i) == 0)
{
//return (0);
ft_find_next_prime(++z);
}
else
i--;
}
return (z);
}
int main(void)
{
int i;
i = 1;
printf("\n\tNUMERO\t---\tSIGIENTE PRIMO\n");
printf("-----------------------------------------------------\n");
while (i <= 100)
{
printf("\t%i\t---\t%i\n", i, ft_find_next_prime(i));
i++;
}
return (0);
}
Thanks so much in advance.
The only thing missing in the recursive code is the return keyword, or an assignment of the variable z. The reeason is that the z passed into parameter is a copy, not the original z variable.
int ft_find_next_prime(int nb)
{
int i;
int z;
i = nb - 1;
z = nb;
while (i > 1)
{
if ((z % i) == 0)
{
//return (0);
return ft_find_next_prime(++z);
// or : z = ft_find_next_prime(++z);
}
else
i--;
}
return (z);
}

Need to generate 4 random numbers without repetition in C programming. 1 to 4

I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}

time limit exceeded error in a simple function C

I'm making a function that reverses numbers less than 100000000. For example, if the input is 1234 then it should return 4321. But I am getting time limit exceeded TLE, I have made break points of my for loops but don't know why. Can you tell me what's wrong with this code?
int reverse(int n){
int i, j=1, d[100000000]={0}, rev=0;
for(i=10; ;i*10){
if(n%i==n){
d[j]=(n%i)/(i/10);
break;
}
d[j++]=(n%i)/(i/10);
}
for(j=1; ;j++){
rev+=(d[j]*(i/10));
i/=10;
if(i==10)
break;
}
return rev;
}
int main(){
printf("%d",reverse(321));
return 0;
}
Use basic knowledge of how numbers work: place value. If you use the % operator to extract the least significant digit from the number, you can build up the reversed number. Try this:
int reverse(int n)
{
int result = 0;
while ( n > 0 )
{
result = result * 10 + (n % 10);
n /= 10;
}
return result;
}

prime factorization of factorial in C

I'm trying to write a program that will print the factorial of a given number in the form:
10!=2^8 * 3^4 * 5^2 * 7
To make it quick lets say the given number is 10 and we have the prime numbers beforehand. I don't want to calculate the factorial first. Because if the given number is larger, it will eventually go beyond the the range for int type. So the algorithm i follow is:
First compute two’s power. There are five numbers between one and ten that two divides into. These numbers are given 2*1, 2*2, …, 2*5. Further, two also divides two numbers in the set {1,2,3,4,5}. These numbers are 2*1 and 2*2. Continuing in this pattern, there is one number between one and two that two divides into. Then a=5+2+1=8.
Now look at finding three’s power. There are three numbers from one to ten that three divides into, and then one number between one and three that three divides into. Thus b=3+1=4. In a similar fashion c=2. Then the set R={8,4,2,1}. The final answer is:
10!=2^8*3^4*5^2*7
So what i wrote is:
#include <stdio.h>
main()
{
int i, n, count;
int ara[]={2, 3, 5, 7};
for(i=0; i<4; i++)
{
count=0;
for(n=10; n>0; n--)
{
while(n%ara[i]==0)
{
count++;
n=n/ara[i];
}
}
printf("(%d^%d)" , ara[i], count);
}
return 0;
}
and the output is (2^3) (3^2) (5^1) (7^1).
I can't understand what's wrong with my code. Can anyone help me, please?
Much simpler approach:
#include <stdio.h>
int main(int argc, char const *argv[])
{
const int n = 10;
const int primes[] = {2,3,5,7};
for(int i = 0; i < 4; i++){
int cur = primes[i];
int total = 0;
while(cur <= n){
total += (n/cur);
cur = cur*primes[i];
}
printf("(%d^%d)\n", primes[i], total);
}
return 0;
}
Your code divides n when it is divisible for some prime number, making the n jumps.
e.g. when n = 10 and i = 0, you get into while loop, n is divisible by 2 (arr[0]), resulting in n = 5. So you skipped n = [9..5)
What you should do is you should use temp when dividing, as follows:
#include <stdio.h>
main()
{
int i, n, count;
int ara[]={2, 3, 5, 7};
for(i=0; i<4; i++)
{
count=0;
for(n=10; n>0; n--)
{
int temp = n;
while(temp%ara[i]==0)
{
count++;
temp=temp/ara[i];
}
}
printf("(%d^%d)" , ara[i], count);
}
return 0;
}
For finding factorial of a no pl. try this code:
#include <stdio.h>
int main()
{
int c, n, fact = 1;
printf("Enter a number to calculate it's factorial\n");
scanf("%d", &n);
for (c = 1; c <= n; c++)
fact = fact * c;
printf("Factorial of %d = %d\n", n, fact);
return 0;
}

How to check whether a no is factorial or not?

I have a problem, then given some input number n, we have to check whether the no is factorial of some other no or not.
INPUT 24, OUTPUT true
INPUT 25, OUTPUT false
I have written the following program for it:-
int factorial(int num1)
{
if(num1 > 1)
{
return num1* factorial(num1-1) ;
}
else
{
return 1 ;
}
}
int is_factorial(int num2)
{
int fact = 0 ;
int i = 0 ;
while(fact < num2)
{
fact = factorial(i) ;
i++ ;
}
if(fact == num2)
{
return 0 ;
}
else
{
return -1;
}
}
Both these functions, seem to work correctly.
When we supply them for large inputs repeatedly, then the is_factorial will be repeatedly calling factorial which will be really a waste of time.
I have also tried maintaining a table for factorials
So, my question, is there some more efficient way to check whether a number is factorial or not?
It is wasteful calculating factorials continuously like that since you're duplicating the work done in x! when you do (x+1)!, (x+2)! and so on.
One approach is to maintain a list of factorials within a given range (such as all 64-bit unsigned factorials) and just compare it with that. Given how fast factorials increase in value, that list won't be very big. In fact, here's a C meta-program that actually generates the function for you:
#include <stdio.h>
int main (void) {
unsigned long long last = 1ULL, current = 2ULL, mult = 2ULL;
size_t szOut;
puts ("int isFactorial (unsigned long long num) {");
puts (" static const unsigned long long arr[] = {");
szOut = printf (" %lluULL,", last);
while (current / mult == last) {
if (szOut > 50)
szOut = printf ("\n ") - 1;
szOut += printf (" %lluULL,", current);
last = current;
current *= ++mult;
}
puts ("\n };");
puts (" static const size_t len = sizeof (arr) / sizeof (*arr);");
puts (" for (size_t idx = 0; idx < len; idx++)");
puts (" if (arr[idx] == num)");
puts (" return 1;");
puts (" return 0;");
puts ("}");
return 0;
}
When you run that, you get the function:
int isFactorial (unsigned long long num) {
static const unsigned long long arr[] = {
1ULL, 2ULL, 6ULL, 24ULL, 120ULL, 720ULL, 5040ULL,
40320ULL, 362880ULL, 3628800ULL, 39916800ULL,
479001600ULL, 6227020800ULL, 87178291200ULL,
1307674368000ULL, 20922789888000ULL, 355687428096000ULL,
6402373705728000ULL, 121645100408832000ULL,
2432902008176640000ULL,
};
static const size_t len = sizeof (arr) / sizeof (*arr);
for (size_t idx = 0; idx < len; idx++)
if (arr[idx] == num)
return 1;
return 0;
}
which is quite short and efficient, even for the 64-bit factorials.
If you're after a purely programmatic method (with no lookup tables), you can use the property that a factorial number is:
1 x 2 x 3 x 4 x ... x (n-1) x n
for some value of n.
Hence you can simply start dividing your test number by 2, then 3 then 4 and so on. One of two things will happen.
First, you may get a non-integral result in which case it wasn't a factorial.
Second, you may end up with 1 from the division, in which case it was a factorial.
Assuming your divisions are integral, the following code would be a good starting point:
int isFactorial (unsigned long long num) {
unsigned long long currDiv = 2ULL;
while (num != 1ULL) {
if ((num % currDiv) != 0)
return 0;
num /= currDiv;
currDiv++;
}
return 1;
}
However, for efficiency, the best option is probably the first one. Move the cost of calculation to the build phase rather than at runtime. This is a standard trick in cases where the cost of calculation is significant compared to a table lookup.
You could even make it even mode efficient by using a binary search of the lookup table but that's possibly not necessary given there are only twenty elements in it.
If the number is a factorial, then its factors are 1..n for some n.
Assuming n is an integer variable, we can do the following :
int findFactNum(int test){
for(int i=1, int sum=1; sum <= test; i++){
sum *= i; //Increment factorial number
if(sum == test)
return i; //Factorial of i
}
return 0; // factorial not found
}
now pass the number 24 to this function block and it should work. This function returns the number whose factorial you just passed.
You can speed up at least half of the cases by making a simple check if the number is odd or even (use %2). No odd number (barring 1) can be the factorial of any other number
#include<stdio.h>
main()
{
float i,a;
scanf("%f",&a);
for(i=2;a>1;i++)
a/=i;
if(a==1)
printf("it is a factorial");
else
printf("not a factorial");
}
You can create an array which contains factorial list:
like in the code below I created an array containing factorials up to 20.
now you just have to input the number and check whether it is there in the array or not..
#include <stdio.h>
int main()
{
int b[19];
int i, j = 0;
int k, l;
/*writing factorials*/
for (i = 0; i <= 19; i++) {
k = i + 1;
b[i] = factorial(k);
}
printf("enter a number\n");
scanf("%d", &l);
for (j = 0; j <= 19; j++) {
if (l == b[j]) {
printf("given number is a factorial of %d\n", j + 1);
}
if (j == 19 && l != b[j]) {
printf("given number is not a factorial number\n");
}
}
}
int factorial(int a)
{
int i;
int facto = 1;
for (i = 1; i <= a; i++) {
facto = facto * i;
}
return facto;
}
public long generateFactorial(int num){
if(num==0 || num==1){
return 1;
} else{
return num*generateFactorial(num-1);
}
}
public int getOriginalNum(long num){
List<Integer> factors=new LinkedList<>(); //This is list of all factors of num
List<Integer> factors2=new LinkedList<>(); //List of all Factorial factors for eg: (1,2,3,4,5) for 120 (=5!)
int origin=1; //number representing the root of Factorial value ( for eg origin=5 if num=120)
for(int i=1;i<=num;i++){
if(num%i==0){
factors.add(i); //it will add all factors of num including 1 and num
}
}
/*
* amoong "factors" we need to find "Factorial factors for eg: (1,2,3,4,5) for 120"
* for that create new list factors2
* */
for (int i=1;i<factors.size();i++) {
if((factors.get(i))-(factors.get(i-1))==1){
/*
* 120 = 5! =5*4*3*2*1*1 (1!=1 and 0!=1 ..hence 2 times 1)
* 720 = 6! =6*5*4*3*2*1*1
* 5040 = 7! = 7*6*5*4*3*2*1*1
* 3628800 = 10! =10*9*8*7*6*5*4*3*2*1*1
* ... and so on
*
* in all cases any 2 succeding factors inf list having diff=1
* for eg: for 5 : (5-4=1)(4-3=1)(3-2=1)(2-1=1)(1-0=1) Hence difference=1 in each case
* */
factors2.add(i); //in such case add factors from 1st list " factors " to " factors2"
} else break;
//else if(this diff>1) it is not factorial number hence break
//Now last element in the list is largest num and ROOT of Factorial
}
for(Integer integer:factors2){
System.out.print(" "+integer);
}
System.out.println();
if(generateFactorial(factors2.get(factors2.size()-1))==num){ //last element is at "factors2.size()-1"
origin=factors2.get(factors2.size()-1);
}
return origin;
/*
* Above logic works only for 5! but not other numbers ??
* */
}

Resources