The recursive function FastExp computes (a^n)(mod m) using the algorithm :
a^n = 1, if n=0;
a^n = [a^(n/2)]^2, if n is even; and
a^n = a(a^[(n-1)/2])^2 if n is odd.
Now I'm sure the algorithm is correct and I followed it exactly, but I get a segmentation fault when I try to run my code. Here's my code -
`#include <stdio.h>
/* function prototype */
int FastExp(int a, int n, int m);
/* There is no error in the main function */
int main()
{
int a, n, m;
printf("Enter three positive numbers a n m: ");
scanf("%d %d %d", &a, &n, &m);
printf("%d^%d(mod %d) is %d\n", a, n, m, FastExp (a, n, m));
return 0;
}
/*
* FastExp(a, 0, m) is 1.
* FastExp(a, 1, m) is a.
* x = FastExp(a, n/2, m)
* FastExp(a, n, m) is x2(mod m) if n is even
* FastExp(a, n, m) is x2a(mod m) if n is odd
*/
/* There is some error in this function */
int FastExp(int a, int n, int m)
{
int an;
if (n == 0)
{
an = 1;
return an;
}
//even
if (n % 2 == 0)
{
an = FastExp (a, n/2, m); // an = a^(n/2)
an = FastExp (an, 2, m); // an = [a^(n/2)]^2
return an;
}
// odd
if (n % 2 == 1)
{
an = FastExp (a, (n-1)/2, m); // an = a^[(n-1)/2]
an = FastExp (an, 2, m); // an = {a^[(n-1)/2]}^2
an = an*a;
return an;
}
return (an % m);
}
I'm guessing it runs into an infinite loop, but I'm not really sure how to correct this. Am I making some basic error? Can anyone explain how to correct it with the least number of instruction changes?
You have the recursive call FastExp (an, 2, m). That leads to infinite recursion.
It's infinite because in the recursive call n is even so you call FastExp (an, 2, m). And in that call n is even so you call FastExp (an, 2, m). And so on.
You fail to stop the recursion in the cases when n == 1 and n == 2.
I don't quite understand your code... From reading the comments for FastExpr, I arrive at this result, which is quite different. Am I missing something here?
/*
* FastExp(a, 0, m) is 1.
* FastExp(a, 1, m) is a.
* x = FastExp(a, n/2, m)
* FastExp(a, n, m) is x2(mod m) if n is even
* FastExp(a, n, m) is x2a(mod m) if n is odd
*/
int FastExp(int a, int n, int m)
{
int x;
if (n == 0) return 1;
if (n == 1) return a;
x = FastExpr(a, n / 2, m); // <-- Good. Converges to zero.
x *= x;
return (n & 1) ? ((x * a) % m) : (x % m);
}
Related
I have a difficulty in implementing the tail recursive solution of the following problem:
There is another recursive relation for the double factorial, which also depends on the factorial, which is the above: (for n<20)
I have to implement a recursive relation of this equation- which I did as the above code that works:
long long factorial(int n) {
if (n < 0)
return 0;
if (n < 1)
return 1;
return n * factorial(n - 1);
}
long long doublefactorial(int n) {
if (n < 0)
return 0;
if (n < 2)
return 1;
return factorial(n) / doublefactorial(n - 1);
}
Now I have to implement the same problem using a tail recursion. can someone show me how to do this because I cant figure it out. (no need to implement the factorial function also in a tail recursive way)
test cases:
5!! = 15
10!! = 3840
18!! = 185,794,560
-10!! = 0
Here is a tail-recursive version of Factorial function:
long factorial(int n, int factor)
{
if (n == 0)
return factor;
return factorial(n-1, factor * n);
}
factorial(5, 1); // 120
Here's a tail-recursive double factorial with a simpler logic:
long doublefactorial(int n, int factor)
{
if (n < 0)
return 0;
if (n < 2)
return factor;
return doublefactorial(n-2, factor * n);
}
printf("%d ", doublefactorial(5,1)); // 15
printf("%d ", doublefactorial(10,1)); // 3840
printf("%d ", doublefactorial(18,1)); // 185794560
If you expand your math a little bit you'll get that the factorial function result is iterating between the numerator and the denominator of the final result.
so this code will do that in Python
def _factorial(n, m):
if n < 0:
return 0
elif n == 0:
return 1.0 * m
return _factorial(n - 1, n * m)
def factorial(n):
return _factorial(n, 1)
def _doublefactorial(n, m, is_even):
if n < 0:
return 0
elif n < 2:
return 1.0 * m
if is_even:
m *= factorial(n)
else:
m /= factorial(n)
return _doublefactorial(n - 1, m, (not is_even))
def doublefactorial(n):
return _doublefactorial(n, 1, True)
And in C:
unsigned int _factorial(const unsigned int n, const unsigned int m) {
if (n < 0) {
return 0;
} else if (n == 0) {
return m;
}
return _factorial(n - 1, n * m);
}
unsigned int factorial(const unsigned int n) {
return _factorial(n, 1);
}
double _doublefactorial(const unsigned int n, const double m, const char is_even) {
double value = m;
if (n < 0) {
return 0;
} else if (n < 2) {
return m;
}
if (is_even) {
value *= factorial(n);
} else {
value /= factorial(n);
}
return _doublefactorial(n - 1, value, !is_even);
}
double doublefactorial(const unsigned int n) {
return _doublefactorial(n, 1, 1);
}
Your definition of this double factorial function is incomplete: you need an initial value such as 0!! = 1. From the recurrence definition, it appears that p!! is the product of all numbers from 1 to p that have the same parity as p:
5!! = 1 * 3 * 5 = 15
6!! = 2 * 4 * 6 = 48
10!! = 2 * 4 * 6 * 8 * 10 = 3840
Computing the double factorial by computing the factorial and dividing by the result of the double factorial of the previous number will fail for numbers larger than 19 because of the limited range of integer types and the exponential growth of the factorial function. The double factorial grows quickly too, but its logarithm grows half as fast as that of the factorial function.
Here is an recursive function:
unsigned long long doublefactorial(int n) {
if (n < 0)
return 0;
if (n < 2)
return 1;
return n * doublefactorial(n - 2);
}
Here is a tail recursive implementation with a helper function:
unsigned long long doublefactorial_helper(int n, unsigned long long res) {
if (n < 2)
return res;
return doublefactorial(n - 2, res * n);
}
unsigned long long doublefactorial(int n) {
return doublefactorial_helper(n, n >= 0);
}
The trick to convert the first function to a tail recursive one is instead of waiting for the result and multiplying then by n, pass an updated intermediary result to the recursive function. The multiplications are performed in the opposite order but will produce the same result (even modulo ULLONG_MAX+1).
FROM HERE
Given a value N, if we want to make change for N cents, and we have
infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how
many ways can we make the change? The order of coins doesn’t matter.
For example, for N = 4 and S = {1,2,3}, there are four solutions:
{1,1,1,1},{1,1,2},{2,2},{1,3}. So output should be 4. For N = 10 and S
= {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5.
Recursive solution. (Can someone please help me understand how to calculate time complexity of this solution)
How to solve T(M,N) = T(M,N-1) + T(M-1,N)
int count( int S[], int m, int n )
{
if (n == 0)
return 1;
if (n < 0)
return 0;
if (m <=0 && n >= 1)
return 0;
return count( S, m - 1, n ) + count( S, m, n-S[m-1] );
}
int main()
{
int i, j;
int arr[] = {1, 2, 3};
int m = sizeof(arr)/sizeof(arr[0]);
printf("%d ", count(arr, m, 4));
getchar(); return 0;
}
I got a modular exponentiation function in C which looks like this.
int modexp(int m, int e, int n)
{
printf("%i\n", m);
printf("%i\n", e);
printf("%i\n", n);
printf("\n");
if(e == 0)
{
return 1;
}
if(e%2 == 1)
{
return modexp(m, e-1, n) * m%n;
}
else
{
int modTemp = modexp(m, (int)(e/2), n);
modTemp = modTemp * modTemp;
return modTemp % n;
}
}
which I am calling in my main() function like this
int p = 3511;
printf("%i\n", modexp(2, p-1, p*p));
When printing the values for m, e and n I get the correct recursion values up to e = 0 in the end. This is when the function should return 1. It definitely returns at that position in the code, however instead of the expected integer 1, I get -6593454 and I have no idea why.
The full code can be found here:
https://gist.github.com/anonymous/7024ac77b2432a381968
any input is highly appreciated...
Multipying an n-bit value with an m-bit value produces a (n+m)-bit result. That's why modexp(m, e-1, n) * m and modTemp * modTemp overflow. You need a widening multiplication to get the full 64-bit result from 32-bit values
return ((int64_t)modexp(m, e-1, n) * m) % n;
...
int64_t modTemp = modexp(m, (int)(e/2), n);
modTemp = modTemp * modTemp;
return modTemp % n;
1 is indeed returned when e == 0, but this return value is a term in the calculations made on previous levels of recursion. If you modify your code like this:
#include <stdio.h>
int modexp(int m, int e, int n)
{
printf("%i\n", m);
printf("%i\n", e);
printf("%i\n", n);
printf("\n");
if(e == 0)
{
printf("returning 1\n");
return 1;
}
if(e%2 == 1)
{
int tmp=modexp(m, e-1, n) * m%n;
printf("returning %d\n",tmp);
return tmp;
}
else
{
int modTemp = modexp(m, (int)(e/2), n);
modTemp = modTemp * modTemp;
modTemp= modTemp % n;
printf("returning %d\n",modTemp);
return modTemp;;
}
}
int main(){
int p = 3511;
printf("%d\n", modexp(2, p-1, p*p));
return 0;
}
You will get this output at the end:
returning 1
returning 2
returning 4
returning 8
returning 64
returning 4096
returning 8192
returning 5473259
returning 10946518
returning 2217782
returning 5855618
returning 11711236
returning 8916378
returning 5505635
returning -1026672
returning 975519
returning 1951038
returning 195330
returning 390660
returning -6593454
-6593454
This shows that the 1 returned for e == 0 is used for further calculations.
At some point your code overflows int, that's why you get a negative number at the end. You should probably use a longer type.
I agree it's an overflow of the modTemp variable. However, for clarity, I'd suggest to only change the type of modTemp from Int to long, and change m/e/n with b/e/m like the following:
#include <stdio.h>
int modexp(int b, int e, int m); // b: base; e: exp; m: modulus
int main()
{
int p = 3511; // given number p
printf("%i\n", modexp(2, p-1, p*p)); // last line printed is the remainder of mod exp
}
int modexp(int b, int e, int m)
{
printf("%i\n", b);
printf("%i\n", e);
printf("%i\n", m);
printf("\n");
if(e == 0)
{
return 1;
}
if(e%2 == 1)
{
return modexp(b, e-1, m) * b%m;
}
else
{
long modTemp = modexp(b, (int)(e/2), m); // !!here modTemp is declared as long!!
modTemp = modTemp * modTemp;
return modTemp % m;
}
}
Your numbers are overflowing. They are most likely 32 or 64-bit signed integers here, which means the maximum size can be 231=2147483648 or 263 = 9223372036854775807. Just look at the size of the modexp(...) multiplied by m%n. That's quite a large number :)
The same goes for modTemp * modTemp
while running this code I am getting floating point exception pls explain why it is coming so.
#include <stdio.h>
int gcd(long int, int);
int main() {
int t, n, a, i;
long int abc;
scanf("%d", &t);
while (t--) {
abc = 1;
scanf("%d", &n);
abc = n * (n - 1);
for (i = n - 2; i > 1; i--) {
a = gcd(abc, i);
abc = ((abc * i) / a);
}
printf("%ld \n", abc);
}
return 0;
}
int gcd(long int a, int b) {
if (b == 0)
return a;
else {
return (b, a % b);
}
}
The else part in gcd function is bogus. You probably wanted to call gcd recursively and instead you are returning a % b. And as a result if a % b == 0 you divide by 0 on line 13.
The expression (b, a % b) is evaluated as two subexpressions separated by comma operator. The value of b is forgotten and the value of the whole expression becomes a % b.
The correct version:
int gcd(long int a, int b) {
if (b == 0)
return a;
else {
return gcd(b, a % b);
}
}
You should change a few things:
1) if(a == 0) instead of b==0 and return variable b
2) Use recursion gcd(b%a, a)
if (a == 0)
return b;
else {
return gcd(b%a, a);
}
And you can also use this short version
return a ? gcd(b%a,a) : b;
Proof:
We have m = n * (m div n) + m Mod n.
This equation is correct even if n = 1, because m div 1 = m and m mod 1 =0.
If n and m mod n it's multiple of d, also m is multiple of d, because n * (m div n) and m mod n / d.
On the other hand if m and n is multiple of e, to because m mod n = m -n * (m div n) is also multiple of e.
I know how to sort an array(i.e. bubble sort) but I don't have any idea how I can sort an array according to n-th term. Could you give me idea or example if there is? Thank you for all appreciated answer.
#edit: how can be the program sensed a number with zeros I mean for 1 program sense 0001 or 00001 .... ?
Example:
2 --> nth digit
4 45 62 1 900 105 --> inputs
Output:
001 004 105 900 045 065
void bubble_sort(int iarr[], int num) {
int i, j, k, temp;
printf("\nUnsorted Data:");
for (k = 0; k < num; k++) {
printf("%5d", iarr[k]);
}
for (i = 1; i < num; i++) {
for (j = 0; j < num - 1; j++) {
if (iarr[j] > iarr[j + 1]) {
temp = iarr[j];
iarr[j] = iarr[j + 1];
iarr[j + 1] = temp;
}
}
printf("\nAfter pass %d : ", i);
for (k = 0; k < num; k++) {
printf("%5d", iarr[k]);
}
}
}
The quick answer is that your comparison function needs to look at the n-th digit instead of the whole number.
So if your original comparison was something like:
if (a < b) // handle a before b case
elseif (b < a) // handle b before a case
you'll want to change it to be:
aDigit = getNthDigit(a, n);
bDigit = getNthDigit(b, n);
if (aDigit < bDigit) // handle a before b case
elseif (bDigit < aDigit) // handle b before a case
You'll also have to implement getNthDigit, which would involve integer division and modulus operators.
Take a look at qsort for what a generic sort function requires. For your specific question, look at the sort algorithm you want to implement (i.e. bubble sort), and replace comparisons of elements with a function call to an order function. Your compare function should then extract the second digit and compare those digits.
Based on your code, you should change if (iarr[j] > iarr[j + 1]) with if(comp_gt(iarr[j], iarr[j + 1])). And, I would implement comp_gt by
int comp_gt(int a, int b)
{
int a_second_digit = (a / 10) % 10;
int b_second_digit = (b / 10) % 10;
return (a_second_digit < b_second_digit);
}
It means that you sort the numbers based on their n-th digit.
In the example you have, you see that the bolded digits (the second digit in every number) are the ones who define the order of the output.
Here is an example on how you can solve it (I am tuning it right now, because the method it uses to find a digit is wrong):
#include <stdio.h>
#include <math.h>
void quickSort(int a[], int first, int last, int n_th);
int pivot(int a[], int first, int last, int n_th);
void swap(int* a, int* b);
int n_th_digit(int number, int n);
void print(int array[], const int N);
int main() {
int test[] = { 7, 9, 1, 3, 6, 5, 2, 4 };
int N = sizeof(test) / sizeof(int);
int n_th = 0; // digit(from the end) to sort by
printf("Size of test array : %d\n", N);
printf("Before sorting : \n");
print(test, N);
quickSort(test, 0, N - 1, n_th);
printf("After sorting : \n");
print(test, N);
return 0;
}
/**
* Quicksort.
* #param a The array to be sorted.
* #param first The start of the sequence to be sorted.
* #param last The end of the sequence to be sorted.
* #param n_th The digit to sort by
*/
void quickSort(int a[], int first, int last, int n_th) {
int pivotElement;
if (first < last) {
pivotElement = pivot(a, first, last, n_th);
quickSort(a, first, pivotElement - 1, n_th);
quickSort(a, pivotElement + 1, last, n_th);
}
}
/**
* Find and return the index of pivot element.
* #param a The array.
* #param first The start of the sequence.
* #param last The end of the sequence.
* #param n_th The digit to sort by
* For example the third digit of 137
* requires n_th to be 0.
*
*/
int pivot(int a[], int first, int last, int n_th) {
int i, p = first;
int pivotElement = a[first];
for (i = first + 1; i <= last; i++) {
if (n_th_digit(a[i], n_th) <= n_th_digit(pivotElement, n_th)) {
p++;
swap(&a[i], &a[p]);
}
}
swap(&a[p], &a[first]);
return p;
}
/**
* Swap the parameters.
* #param a The first parameter.
* #param a The second parameter.
*/
void swap(int* a, int* b) {
// You still can use the swap that
// does not uses an extra variable
// from the C++ implementation.
int temp = *a;
*a = *b;
*b = temp;
}
int n_th_digit(int number, int n) {
if (number < 0)
number *= -1;
return fmod((number / pow(10, n)), 10);
}
/**
* Print an array.
* #param a The array.
* #param N The size of the array.
*/
void print(int a[], const int N) {
int i;
for (i = 0; i < N; i++)
printf("array[%d] = %d\n", i, a[i]);
}
I got the how to find the n-th digit from here and the quicksort from here.
Replace
void bubble_sort(int iarr[], int num) {
....
if (iarr[j] > iarr[j + 1])
With
void bubble_sort(int iarr[], int num, int term) {
unsigned pow10 = upow10(term - 1);
....
if (compareu(iarr[j], iarr[j + 1], pow10) > 0)
// To calculate pow(10, x) quickly
static unsigned upow10(unsigned y) {
unsigned z = 1;
unsigned base = 10;
while (y) {
if (y & 1) {
z *= base;
}
y >>= 1;
base *= base;
}
return z;
}
int compareu(int a1, int a2, unsigned pow10) {
unsigned b1 = abs(a1);
unsigned b2 = abs(a2);
b1 = (b1 / pow10) % 10;
b2 = (b2 / pow10) % 10;
if (b1 > b2) return 1;
if (b1 < b2) return -1;
return (a1 > a2) - (a1 < a2);
}
[Edit] per OP's update
Q: how can be the program sensed a number with zeros I mean for 1 program sense 0001 or 00001?
A: That is part of the code that reads input which is not posted. If code needs to distinguish between "0001" and "00001", then the whole problem is one of strings and not integers. In that case save each element as a string and do compares from a textual point-of-view.
Yet I suspect that is not the true coding goal. Simply use arithmetical compares and not be concerned with differing leading zeros.
The printf() function is another matter. To print at least term digits with leading 0, use "%0*d".
term = 2; // or 6 or 9, etc.
// printf("%5d", iarr[k]);
printf("%0*d ", term, iarr[k]);