Related
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
I need to input this equation and there's a factorial in it. I would like to know if there was something like * = multiplication or pow(1,3) for factorial of something in C.
term = pow(-1, K) * pow(x, 2K)/(2K)
The factorial would be for the last 2K.
Rarely you need a function for computing factorials. Factorials grow so fast that a look-up-table is sufficient for the few values for which the computation does not overflow. If you are computing terms in a loop, you can avoid computing the factorial using an accumulator for the entire term.
K = 0;
term = 1;
while (K<N) {
/* use term */
do_something_with(term);
/* update term for new value of K */
K += 1;
term = -term * x*x / (2*K*(2*K-1));
}
If that seems unclear to you, you can first derive this program where the accumulators are explicit, and then combine the update step into a single variable like above. This program will still have problems with the factorial computation blowing up.
K = 0;
pow_minus_1_K = 1;
pow_x_2K = 1;
factorial_2K = 1;
while (K<N) {
/* compute term */
term = pow_minus_1_K * pow_x_2K/factorial_2K;
/* update accumulators for new value of K */
K += 1;
pow_minus_1_K = -pow_minus_1_K;
pow_x_2K *= x*x;
factorial_2K *= 2*K*(2*K-1);
}
Factorials are easy to calculate, after all n! is just the product of all numbers up to n. But there is a practical problem: Factorials overflow pretty quickly. A 32-bit int can hold 12!, a 64-bit int 20!.
Depending on how your series converges, you might overflow the valid range.
With approximation series like yours, it is usually better to find a means to represent term k by means of term k − 1. In your case:
term = pow(-1, k) * pow(x, 2*k) / fact(2*k)
you can represent a term as
term[k + 1] = -term[k] * pow(x, 2) / ((2*k - 1) * (2*k - 2))
and your series becomes:
double f(double x)
{
double term = 1.0;
double res = term;
int k = 0;
while (k < 100) {
double old = res;
term = -term * (x / (2*k + 1)) * (x / (2*k + 2));
res += term;
if (res == old) break;
k++;
}
return res;
}
This function will use at most 100 iterations to calculate the cosine. It stops when the term doesn't contribute to the result. In practice, it reaches the result with about 10 iterations, so in that case the regular factorial calculations would have been accurate enough. Still, calculating them over and over is wasteful.
There is no predefined function for factorial, but it can be recursively implemented as follows.
int factorial( int a )
{
if ( 0 == a )
return 1;
else
return a * factorial( a - 1 );
}
People who like the ? operator might implement the function as follows.
int factorial( int a )
{
return 0 == a ? 1 : ( a * factorial( a - 1 ) );
}
If a non-recursive formulation is desired, the implementation can be done as follows.
int factorial( int a )
{
int Result = 1;
for ( int i = a; i > 0; Result *= i, i-- );
return Result;
}
If for some reason recursive functions leave you scratching your head, you can also implement it without recursion:
/* calculate n factorial */
unsigned long long nfact (int n)
{
if (n <= 1) return 1;
unsigned long long s = n;
while (--n)
s *= n;
return s;
}
(note: it is up to you to you to implement a test for overflow, if desired)
I think using recursion for this problem is a good way to get started with recursion and understand the way it works, but it's not efficient enough since you're calling a function every time. If you want to know why, do a test and see how long it takes. Although I should say, the iterative method is not significantly better either.
From Code Complete by Steve McConnell:
Don't use recursion for factorials or Fibonacci numbers
One problem with computer-science textbooks is that they present silly
examples of recursion. The typical examples are computing a factorial
or computing a Fibonacci sequence. Recursion is a powerful tool, and
it's really dumb to use it in either of those cases. If a programmer
who worked for me used recursion to compute a factorial, I'd hire
someone else.
So when keep that in mind when going over the recursive versions that are posted here. Now, how to write one.
Basically you have a base case for when the number is less than 1, and a general recursive case. You generally have a base case and a recursive case in a recursive function. For a factorial, it would look something like this:
int factorial_rec(int number)
{
if (number == 0)
{
return 1;
}else
{
return number * factorial_rec(number - 1);
}
}
long fact(int num)
{
if(num==0)
return 1;
else
return num*fact(num-1);
}
Include the above code and call this method to get factorial of a number.
The code to find factorial of a given number using recursive algorithm can be as shown below :
#include<stdio.h>
int fact(int n)
{
if(!n)
return 1;
else
return (n*fact(n-1));
}
void main()
{
int n;
printf("Enter number : ");
scanf("%d",&n);
printf("\nFactorial of %d is : %d",n,fact(n));
}
#include<stdio.h>
long factorial(int n)
{
if (n == 0)
return 1;
else
return(n * factorial(n-1));
}
void main()
{
int number;
long fact;
printf("Enter a number: ");
scanf("%d", &number);
fact = factorial(number);
printf("Factorial of %d is %ld\n", number, fact);
return 0;
}
#include<stdio.h>
int main()
{
int i,fact=1,number;
printf("Enter a number: ");
scanf("%d",&number);
for(i=1;i<=number;i++){
fact=fact*i;
}
printf("Factorial of %d is: %d",number,fact);
return 0;
}
#include <stdio.h>
int main() {
int n, i;
unsigned long long fact = 1;
printf("Enter an integer: ");
scanf("%d", &n);
// shows error if the user enters a negative integer
if (n < 0)
printf("Error! Factorial of a negative number doesn't exist.");
else {
for (i = 1; i <= n; ++i) {
fact *= i;
}
printf("Factorial of %d = %llu", n, fact);
}
return 0;
}
I have a recursive function and I want to count the number of zeros in it, how do I use a constant to count the zero and not allowing to reset.
int countZeros(int num)
{
int count = 0;
if (num > 0)
{
if (num % 10 == 0)
count++;
return(countZeros(num / 10));
}
if (num <= 0)
return count;
}
For my code, my count will reset once my return function is called. Is there any way to prevent this from happening? I have to return the value back to my main function and display from there.
case 9:
printf("Enter a number: ");
scanf("%d", &recursion);
printf("number of zeros = %d",countZeros(recursion));
break;
Try this code:
int countZeros(int num)
{
if (num > 0 && num % 10 == 0)
return(countZeros(num / 10)+1);
else
return 0;
}
It will work in the same way, only note that if your num is negative (but still with zeroes, like -100, it will return 0).
In order to work with negative numbers, use this:
int countZeros(int num)
{
if (num !=0 && num % 10 == 0)
return (countZeros(num / 10)+1);
else
return 0;
}
Make your int static:
static int count = 0;
Here is a sample run.
Pointers will work as well:
#include <stdio.h>
int countZeros(int num, int * count)
{
if (num > 0)
{
if (num % 10 == 0)
(*count)++;
return(countZeros(num / 10,count));
}
if (num <= 0)
return *count;
}
int main(void)
{
int count = 0;
printf("Count = %d",countZeros(1000,&count) );
return 0;
}
Avoid static variables, they are evil, for multiple reasons...
The only algorithm that works, and doesn't just count the trailing zeros, is ring0's answer, but please, local variables are free, and explicit code helps not only the reader, but is much more maintainable.
Run it here.
#include <stdio.h>
int main(void)
{
printf("Count = %d\n", countZeros( 10100) );
printf("Count = %d\n", countZeros(-10010) );
return 0;
}
int countZeros(int num)
{
// Final stop
if (num == 0 )
return 0;
// Recursion for numbers to the left
int count = countZeros(num / 10);
// Increase count if current unit is 0
if (num % 10 == 0)
count++;
return count;
}
Explanation:
For the recursion, you need a converging process and a stop condition.
The first IF is the base case. Dividing 3 (or -3 for that matter) by 10 will always end up being 0. This is what ends the recursion (stop condition).
The second and last blocks are interchangeable. If the rightmost number is 0, you increase the counter, but then, you also need to add the count result from all the numbers to the left. This is done by seeding it only what you didn't count, hence the division by 10 (to converge).
Both division and modulo works the same for negative and positive numbers, so you keep the behavior for both ends of the integer range.
Without any more variable
int countZeros(int n) {
return n ? (n % 10 ? 0:1)+countZeros(n/10) : 0;
}
countZeros works also with negative numbers.
Example
printf("%d\n", count( 10001)); // prints "3"
printf("%d\n", count(-10001)); // prints "3"
use static variable.
static int count = 0;
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 ??
* */
}
I wrote this program:
#include <stdio.h>
/*Part B
Write a program that:
defines an array of 10 ints
assigns factorial(x) to array element x, for x in the range 0 through 9, inclusive
copies those array elements into a second array of 10 ints, but in reverse order (i.e., element 0 is factorial(9), element 1 is factorial(8), and so on)
prints out that second array to the terminal*/
int factorial(int n){
int factorial = 1;
while(n>1){
factorial = n*factorial;
}
return factorial;
}
int main(int argc, char **argv){
int arr1[10];
int arr2[10];
int i = 0;
for(i = 0; i<10; i++){
printf("%d", i);
arr1[i] = factorial(i);
}
for(i = 9; i>=0; i--){
arr2[i] = arr1[9-i];
printf("%d ", arr2[i]);
}
printf("\n");
return 0;
}
but when I run it it just sits there. I think it's something to do with the call to factorial, because when I comment that out it works instantly, but with it in, it isn't even getting to the first printf.
What am I doing wrong?
while(n > 1){
factorial = n*factorial;
}
you missed n--;
Your while loop:
while(n>1){
factorial = n*factorial;
}
Will run forever. There is nothing in that loop that can change n, so if the loop is entered then we know n will always be greater than 1. You should decrement n within your loop:
while(n > 1){
factorial = n--*factorial;
}
If you aren't used to seeing decremenent like that you can also do it on a new line:
while(n>1){
factorial = n*factorial;
n--;
}
You should decrement n in factorial function.
You have a wrong implementation of factorial method.
int factorial(int n){
int factorial = 1;
while(n>1){
factorial = n*factorial;
n--;
}
return factorial;
}
Your code simply didn't do anything with n variable and kept multiplying, without ever decreasing n value. Hope this helps