I was reading about Euclid's algorithm to calculate GCD and found the following code:
#include <stdio.h>
int main()
{
int m, n;
scanf("%d%d", &n, &m);
if (n < 0) n = -n;
if (m < 0) m = -m;
while(n != 0)
{
int temp = n;
n = m % n;
m = temp;
}
if(m != 0)
printf("The gcd is %d\n", m);
return 0;
}
But I have some questions:
why if n<0 or m<0 we let n=-n or m=-m
What if m==0 what should I return? The smallest possible GCD is 1 but this function doesn't return anything in this case... (If we ignore return 0 which is necessary for main)
The second part of the algorithm only works for non-negative values of m and n. Since gcd(m,n) = gcd(|m|,|n|) they are made positive.
If m = 0 and n != 0 the gcd is n and vica versa.
If both n and m are 0 the gcd is undefined because every number is a divisor of 0. Therefore, nothing is printed in this case.
Answer 1:
This algorithm works properly for the non-negative value m and positive value n.
Example:
GCD(-6, 2) = GCD(6, -2) = GCD(-6, -2) = GCD(6, 2) = 2
Answer 2:
If m == 0 then this function will return GCD equal n
Related
Here is a code to exponentiate a number to a given power:
#include <stdio.h>
int foo(int m, int k) {
if (k == 0) {
return 1;
} else if (k % 2 != 0) {
return m * foo(m, k - 1);
} else {
int p = foo(m, k / 2);
return p * p;
}
}
int main() {
int m, k;
while (scanf("%d %d", &m, &k) == 2) {
printf("%d\n", foo(m, k));
}
return 0;
}
How do I calculate the time complexity of the function foo?
I have been able to deduce that if k is a power of 2, the time complexity is O(log k).
But I am finding it difficult to calculate for other values of k. Any help would be much appreciated.
How do I calculate the time complexity of the function foo()?
I have been able to deduce that if k is a power of 2, the time complexity is O(logk).
First, I assume that the time needed for each function call is constant (this would for example not be the case if the time needed for a multiplication depends on the numbers being multiplied - which is the case on some computers).
We also assume that k>=1 (otherwise, the function will run endlessly unless there is an overflow).
Let's think the value k as a binary number:
If the rightmost bit is 0 (k%2!=0 is false), the number is shifted right by one bit (foo(m,k/2)) and the function is called recursively.
If the rightmost bit is 1 (k%2!=0 is true), the bit is changed to a 0 (foo(m,k-1)) and the function is called recursively. (We don't look at the case k=1, yet.)
This means that the function is called once for each bit and it is called once for each 1 bit. Or, in other words: It is called once for each 0 bit in the number and twice for each 1 bit.
If N is the number of function calls, n1 is the number of 1 bits and n0 is the number of 0 bits, we get the following formula:
N = n0 + 2*n1 + C
The constant C (C=(-1), if I didn't make a mistake) represents the case k=1 that we ignored up to now.
This means:
N = (n0 + n1) + n1 + C
And - because n0 + n1 = floor(log2(k)) + 1:
floor(log2(k)) + C <= N <= 2*floor(log2(k)) + C
As you can see, the time complexity is always O(log(k))
O(log(k))
Some modification added to output a statistics for spread sheet plot.
#include <stdio.h>
#include <math.h>
#ifndef TEST_NUM
#define TEST_NUM (100)
#endif
static size_t iter_count;
int foo(int m, int k) {
iter_count++;
if (k == 0) {
return 1;
} else if(k == 1) {
return m;
} else if (k % 2 != 0) {
return m * foo(m, k - 1);
} else {
int p = foo(m, k / 2);
return p * p;
}
}
int main() {
for (int i = 1; i < TEST_NUM; ++i) {
iter_count = 0;
int dummy_result = foo(1, i);
printf("%d, %zu, %f\n", i, iter_count, log2(i));
}
return 0;
}
Build it.
gcc t1.c -DTEST_NUM=10000
./a > output.csv
Now open the output file with a spread sheet program and plot the last two output columns.
For k positive, the function foo calls itself recursively p times if k is the p-th power of 2. If k is not a power of 2, the number of recursive calls is strictly inferior to 2 * p where p is the exponent of the largest power of 2 inferior to k.
Here is a demonstration:
let's expand the recursive call in the case k % 2 != 0:
int foo(int m, int k) {
if (k == 1) {
return m;
} else
if (k % 2 != 0) { /* 2 recursive calls */
// return m * foo(m, k - 1);
int p = foo(m, k / 2);
return m * p * p;
} else { /* 1 recursive call */
int p = foo(m, k / 2);
return p * p;
}
}
The total number of calls is floor(log2(k)) + bitcount(k), and bitcount(k) is by construction <= ceil(log2(k)).
There are no loops in the code and the time of each individual call is bounded by a constant, hence the overall time complexity of O(log k).
The number of times the function is called (recursively or not) per power call is proportional to the minimum number of bits in the exponent required to represent it in binary form.
Each time you enter in the function, it solves by reducing the number by one if the exponent is odd, OR reducing it to half if the exponent is even. This means that we will do n squares per significant bit in the number, and m more multiplications by the base for all the bits that are 1 in the exponent (which are, at most, n, so m < n) for a 32bit significant exponent (this is an exponent between 2^31 and 2^32 the routine will do between 32 and 64 products to get the result, and will reenter to itself a maximum of 64 times)
as in both cases the routine is tail-recursive, the code you post can be substituted with an iterative code in which a while loop is used to solve the problem.
int foo(int m, int k)
{
int prod = 1; /* last recursion foo(m, 0); */
int sq = m; /* squares */
while (k) {
if (k & 1) {
prod *= sq; /* foo(m, k); k odd */
}
k >>= 1;
sq *= sq;
}
return prod; /* return final product */
}
That's huge savings!!! (between 32 multiplications and 64 multiplications, to elevate something to 1,000,000,000 power)
Is there a fast algorithm for calculating binomial coefficients and leaving the results binary. For example, (10 choose 8) = 101101. I do not need to convert my results to base 10, instead I want to store my results as binary strings. I was asking this question before reinventing the wheel.
I found the most efficient way. It's performing a prime factorization of the binomial coefficient, then converting to binary. I've added really fast code for finding the prime factorization of a binomial coefficient. It's called Kummer's theorem and you can use this online calculator to verify your results. The factorization algorithm is from this Jstor paper. This is a Haskell version if you're into that kind of stuff. Note you need to first generate a list of primes on your own. Then test individual primes. Also, the fundamental theorem of arithmetic is at work.
//Note primeNumber is always less than n
//Inputs n,k,primeNumber
//Output: e (the exponent of prime number)
//Note: 0 means primeNumber is not a factor of this binomial coefficient
//Example: (n=10,k=3,primeNumber=3), e = 1
//So if you had a list of primes 2,3,5 then for each you get e=3,e=1,e=1. (10,3) = 2^3 *3^1 * 5 ^1
int BinomialFactorization(int n, int k, int primeNumber)
{
int a = 0;
int b = 0;
int exponent = 0;
int r = 0;
//Finds smaller value between n and n-k since (n choose k) == (n choose n-k)
//Algorithm only works when k < n/2
if(k > (n/2))
{
k = n - k;
}
//Speeds up according to paper
if(primeNumber > n - k)
{
return 1;
}
//Speeds up according to paper
if(primeNumber > n/2)
{
printf("%d", 0);
return 0;
}
if(primeNumber * primeNumber > n)
{
if(n % primeNumber < k % primeNumber)
{
return 1;
}
else
{ //Saw this on online calculator
return 0;
}
}
//Changing base algorithm
while(n > 0)
{
a = n % primeNumber;
n = n / primeNumber;
b = k % primeNumber + r;
k = k / primeNumber;
if(a < b)
{
exponent = exponent + 1;
r = 1;
}
else
{
r = 0;
}
}
return exponent;
}
I am getting negative and positive result : when I enter(n value odd) odd term produces even or and even term produces odd value. I have already made function for factorial it works fine.
#include <stdio.h>
#include <math.h>
#define PI 3.14159f
int factorial(int n);
float sine(float , int);
int i;
void main(){
float degree;
float radian;
float result;
int n;
printf("Enter the angle in degree: ");
scanf("%f",°ree);
printf("Enter the iteration: ");
scanf("%d",&n);
radian = degree * PI / 180;
result = sine(radian,n);
printf("%d",factorial(n));
printf("\n");
printf("sin%.2f = %.3f",degree,result);
}
int factorial(int n)
{
if(n==0)
return 1;
else if (n==1)
return 1;
else
return (n*factorial(n-1));
}
float sine(float an, int n)
{
if (an==0)
return 0;
else if(n>=0)
if(n%2==1)
return (sine(an,n-2) - pow(an,n)/factorial(n)) * pow(-1,n);
else
return (sine(an,2*n-1) - pow(an,2*n+1)/factorial(2*n+1)) *-1 ;
}
float sine(float an, int n)
{
if (an == 0)
return 0;
The above condition returns 0 for sin(0) so it is of no use in rest of the recursion and it works fine.
else if(n >= 0)
if(n%2 == 1)
return (sine(an,n-2) - pow(an,n)/factorial(n)) * pow(-1,n);
else
return (sine(an,2*n-1) - pow(an,2*n+1)/factorial(2*n+1)) *-1 ;
Lets see where this part of your function goes, by substituting the value of n:
Suppose we are start with degree = 30 and number of iterations = 3
Then:
n = 3;
n is odd so function returns:
((sine(an, 3-2) - (float)pow(an, 3) / factorial(3)) * -1);
n = 1;
n is again odd so function returns:
((sine(an, 1-2) - (float)pow(an, 1) / factorial(1)) * -1);
n = -1;
This time n < 0 so if-else conditions are skipped and some garbage value is returned because you did not tell your program what to return at n = 0
So you need your sine-function to return a default value when n = 0
pow(-1,n) will always return -1 for odd values of n, and 1 for even values of n. So the sign of output of sine() function is not changing alternately like in the series.
Answering to the comment: Why the sign seems to change for odd or even,
In your code values of n are skipping the even numbers, instead of decreasing n by 1 per call, you are passing only odd numbers.
return (sine(an,n-2) - pow(an,n)/factorial(n)) * pow(-1,n);
so what you get in the end is a sum of negatives; And when you start with a even value of n like 2, then sine() is called with odd value of n the second time which is (2*n-1) which again returns a sum of negatives.
Heres what you can do:
float sine(float an, int n)
{
if (an == 0 || n == 0)
return 0; //to end the recursion when number of iterations are finished
else
return -1*pow(-1,n)*pow(an,2*n-1)/factorial(2*n-1) + sine(an, n - 1);
}
// `-1*pow(-1,n)` returns a negative term for even value of n, and postive term for odd value of n as required. You dont need separate if-else for that
I need to find the biggest divisor of a positive integer and output it. Divisor should not be 1 or be equal to the integer itself. If it's a prime number the output should be "0". I have this code so far. However it doesn't work. It only works when I use "break" instead of "return 0" statement, but according to the task I should not use break :( How can I fix it? Thnx
#include <stdio.h>
int main() {
int input, maxDiv;
int div = 2;
scanf("%d", &input);
for ( ; div <= input/2; div += 1 ) {
if ( input % div == 0 ) {
maxDiv = input / div;
return 0;
} else {
maxDiv = 0;
}
}
printf("%d\n", maxDiv);
return 0;
}
You can rewrite it this way
int main(){
int input, maxDiv = 0;
int div = 2;
scanf("%d", &input);
for(; !maxDiv; div++)
if(!(input%div))
maxDiv = input/div;
printf("%d\n", ( maxDiv == 1 || input < 0 ? 0 : maxDiv ) );
return 0;
}
It is an infinite loop that will exit as soon as maxDiv != 0. The complexity is O(sqrt (n)) as there is always a divisor of n less than or equal to sqrt(n), so the code is bound to exit (even if input is negative).
I forgot, you have to handle the case where input is zero.
Maybe you can declare a flag?
#include <stdio.h>
int main() {
int input, maxDiv;
int div = 2;
char found = 0;
scanf("%d", &input);
for ( ; div <= input/2 && !found ; div += 1 ) {
if ( input % div == 0 ) {
maxDiv = input / div;
found = 1;
} else {
maxDiv = 0;
}
}
printf("%d\n", maxDiv);
return 0;
}
You can stop the loop when you reach sqrt(input)... it's not that difficult to find a perfectly good integer sqrt function.
There's not a lot of point dividing by all the even numbers after 2. In fact there's not a lot of point dividing by anything except the primes. It's not hard to find the primes up to sqrt(INT_MAX) (46340, for 32-bit integer)... there are tables of primes freely available if you don't want to run a quick sieve to generate same.
And the loop...
maxdiv = 0 ;
i = 0 ;
sq = isqrt(input) ;
while ((maxdiv == 0) && (prime[i] < sq))
{
if ((input % prime[i]) == 0)
maxdiv = input / prime[i] ;
i += 1 ;
} ;
assuming a suitable integer sqrt function and a table of primes... as discussed.
Since you are looking for the largest divisor, is there a reason you're not looping backward to 2? If there isn't, then there should be no need for a break statement or any special logic to exit the loop as you should keep looping until div is greater than input / 2, testing every value until you find the largest divisor.
maxDiv = -1;
for (div = input / 2;
div >= 2 && maxDiv == -1;
--div)
{
if (input % div == 0)
maxDiv = div;
}
maxDiv += (maxDiv == -1);
printf ("%d\n", maxDiv);
I added the extra condition of maxDiv being -1, which is like adding a conditional break statement. If it is still -1 by the end of the loop, then it becomes 0 because maxDiv += 1 is like writing maxDiv = -1 + 1, which is 0.
Without any jump statement such as break, this sort of test is what you must do.
Also, regarding your code, if I input 40, the if statement will be triggered when div is 2, and the program will end. If the return 0 is changed to a break, maxDiv will be 2, not 20. Looping backward will find 20 since 40/2=20, and 40%20==0.
Let us denote D to the max divisor of a given composite number N > 1.
Then, obviously, the number d = N / D is the min non-trivial divisor of N.
If d would not a primer number, then d would have a non-trivial divisor p < d.
By transitivity, this implies that p is a divisor of N, but this fact would contradict the fact that d is the min divisor of N, since p < d.
So, d must be a prime number.
In particular, it is enouth to search over those numbers which are less than sqrt(N), since, if p is a prime number greater than sqrt(N) which divies N, then N / p <= sqrt(N) (if not, *p * (N / p) > sqrt(N)sqrt(N) == N, wich is absurd).
This shows that it's enough to do the search the least divisor d of N just within the range of primer numbers from 2 to sqrt(N).
For efficiency, the value sqrt(N) must be computed just once before the loop.
Moreover, it is enough a rough approximation of sqrt(N), so we can write:
#include <math.h>
#include <stdio.h>
int main(void)
{
int N;
scanf("%d",&N);
// First, we discard the case in that N is trivial
// 1 is not prime, but indivisible.
// Change this return if your want.
if (N == 1)
return 0;
// Secondly, we discard the case in that N is even.
if (N % 2 == 0)
return N / 2;
// Now, the least prime divisor of N is odd.
// So, we increment the counter by 2 in the loop, by starting in 3.
float sqrtN = fsqrt(N); // square root of N in float precision.
for(d = 3; d <= sqrtN; d += 2)
if (N % d == 0)
return N/d;
// If the loop has reached its end normally,
// it means that N is prime.
return 0;
}
I think that the problem is not well stated, since I consider that a better flag to signalize that N is prime would be a returned value of 1.
There are more efficient algorithms to determine primality, but they are beyond the scope of the present question.
I have read about Fermat's primality test... it was nice but there was one flaw about Carmichael number... it shows that it coulnd't find the distiguish them with prime numbers..
My code:
bool fermat(long long p,int itr)
{
if(p==1)return false;
for(int i=0;i<itr;i++)
{
long long a=rand()%(p-1)+1;
if(modulo(a,p-1,p)!=1)
return false;
else
return true;
}
}
How can I find that p is prime without getting into the problem of Carmichael number? Any modification of this algo?
Pseudocode for the Miller-Rabin test, which gives a probabilistic answer, is shown below:
function isPrime(n, k=5)
if n < 2 then return False
for p in [2,3,5,7,11,13,17,19,23,29]
if n % p == 0 then return n == p
s, d = 0, n-1
while d % 2 == 0
s, d = s+1, d/2
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
if x == n-1 then next i
return False
return True
That uses k (default 5) random bases. If you know in advance the limit on n you could chose a set of bases that gives a deterministic answer; see miller-rabin.appspot.com for lists of bases for various n.