How to make a function in c++ to determine if two entered numbers are relatively prime (no common factors)?
For example "1, 3" would be valid, but "2, 4" wouldn't.
Galvanised into action by Jim Clay's incautious comment, here is Euclid's algorithm in six lines of code:
bool RelativelyPrime (int a, int b) { // Assumes a, b > 0
for ( ; ; ) {
if (!(a %= b)) return b == 1 ;
if (!(b %= a)) return a == 1 ;
}
}
Updated to add: I have been out-obfuscated by this answer from Omnifarious, who programs the gcd function thus:
constexpr unsigned int gcd(unsigned int const a, unsigned int const b)
{
return (a < b) ? gcd(b, a) : ((a % b == 0) ? b : gcd(b, a % b));
}
So now we have a three-line version of RelativelyPrime:
bool RelativelyPrime (int a, int b) { // Assumes a, b > 0
return (a<b) ? RelativelyPrime(b,a) : !(a%b) ? (b==1) : RelativelyPrime (b, a%b);
}
One of the many algorithms for computing the Greatest Common Denominator.
Related
I'm having an issue with this code:
The problem is I'm constantly getting warning C4715 despite the fact .exe is running correctly and it gives correct answer to a problem I'm trying to resolve. The warning makes it impossible to pass the task inside the app. Please give me a clue why 'return' used by me in the if sentences doesn't work.
#include <utility>
#include <iostream>
std::pair<int, int> solve(int a, int b) {
if (a == 0 || b == 0) {
std::pair <int, int> kek(a, b);
return kek;
}
else if (a >= 2 * b) {
a = (a - (2 * b));
solve(a, b);
}
else if (b >= 2 * a) {
b = (b - (2 * a));
solve(a, b);
}
else {
std::pair <int, int> kek(a, b);
return kek;
}
}
int main() {
bool result{ solve(22, 5) == std::make_pair(0,1) };
std::cout << result;
return 0;
}
Your solve function won't execute return statement if a == 0 || b == 0 is not true and either one of a >= 2 * b or b >= 2 * a is true.
It seems that the two solve(a, b); in the solve function should be return solve(a, b);.
As mentioned here: gcd(a,b) = gcd(-a,b) = gcd(-a,-b). However when I use following code, I get different output for input being (-4,-8).
gcd(x,y) gives -4 wheras gcd(abs(x),abs(y)) gives 4.
Can some one help me understand where I am wrong.
int gcd(int a ,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int main()
{
int x,y;
cin>>x>>y;
cout<<gcd(x,y)<<endl; // gives -4
cout<<gcd(abs(x),abs(y))<<endl; //gives 4
return 0;
}
You're not taking into account that the output range has a plus or minus sign in it which breaks your algorithm, it's asserting that negative numbers and positive numbers are to be treated as the positive integers. Formal set theory in discrete mathematics has a different jargon set for symbols that are incompatible with most programming languages.
Greatest Common Denominator in C++ using recursion
int GCD(int A,int B)
{
if(A==0) return B;
if(B==0) return A;
A=abs(A);
B=abs(B);
if(A>B) return GCD(B,A);
return GCD(B%A,A);
}
Your algorithm cannot cover all positive and negative numbers. Use the code below.
int gcd(int a, int b){
a = abs(a);b = abs(b);
if (a == 0)
return b;
if (b == 0)
return a;
if (a == b)
return a;
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
I am using Euclid algorithm but it is causing run time error due to stack overflow.
I am unable to calculate HCF of a very large number and a small number
I believe you're writing a function like this:
int hcf(int a, int b){
if (a == 0){
return b;
}
else if (b == 0){
return a;
}
else if (a > b){
return hcf(b, a - b); // this is subtraction
}
else if (a < b){
return hcf(a, a - b); // this is subtraction
}
}
...and you're calling it with something like
int q = hcf(100000000, 1);
Well... Without optimisation that will create 1 billion recursion calls. It's definite that your program will run out of stack capacity.
My personally preferred solution is give up recursive methods and use an iterative one. The code can then be simplified to a single loop:
int hcf(int a, int b){
while(a != 0 && b != 0){
if (a > b){
a = a - b;
}
else{
b = b - a;
}
}
if (a == 0){
return b;
}
else{
return a;
}
}
If you insist on using recursive methods, replace subtraction with modulus.
else if (a > b){
-> return hcf(b, a % b); // this is modulus
}
else if (a < b){
-> return hcf(a, a % b); // this is modulus
}
Correctly implemented algorithm shall use at most log(number) steps, and thus not cause stack overflow. I suppose you use the following algorithm:
gcd(a, 0) = a
gcd(a, b) = gcd(a-b, b)
which looks like this in C++:
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(std::max(a, b) - std::min(a, b), std::min(a, b));
}
}
This is not optimal. Instead you shall use the following relation
gcd(a, 0) = a
gcd(a, b) = gcd(b, a mod b)
which looks like this in C++:
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
This code will actually take only log(ab) steps, and thus not cause stack overflow
Also you may try to enable optimisation: it should allow to collapse both of the functions call into non-recursive versions (as this is a tail recursion). Note that it is not certain if it will increase speed.
As a matter of caution: be careful with the negative numbers, the % operator works incorrectly for them
For example, A=10^17, B=10^17, C=10^18.
The product A*B exceeds the limit of long long int.
Also, writing ((A%C)*(B%C))%C doesn't help.
Assuming you want to stay within 64-bit integer operations, you can use binary long division, which boils down to a bunch of adds and multiply by two operations. This means you also need overflow-proof versions of those operators, but those are relatively simple.
Here is some Java code that assumes A and B are already positive and less than M. If not, it's easy to make them so beforehand.
// assumes a and b are already less than m
public static long addMod(long a, long b, long m) {
if (a + b < 0)
return (a - m) + b; // avoid overflow
else if (a + b >= m)
return a + b - m;
else
return a + b;
}
// assumes a and b are already less than m
public static long multiplyMod(long a, long b, long m) {
if (b == 0 || a <= Long.MAX_VALUE / b)
return a * b % m; // a*b > c if and only if a > c/b
// a * b would overflow; binary long division:
long result = 0;
if (a > b) {
long c = b;
b = a;
a = c;
}
while (a > 0) {
if ((a & 1) != 0) {
result = addMod(result, b, m);
}
a >>= 1;
// compute b << 1 % m without overflow
b -= m - b; // equivalent to b = 2 * b - m
if (b < 0)
b += m;
}
return result;
}
You can use
The GNU Multiple Precision Arithmetic Library
https://gmplib.org/
or
C++ Big Integer Library
https://mattmccutchen.net/bigint/
If you work only with power of 10 numbers, you could create a simple class with 2 members: a base and the power of 10, so A=10^17 would be {1, 17}. Implementing adding, subtracting, multiply and division is very easy and so is the print.
I need a function with a header like this:
bool is_prefix(int a, int b, int* c) {
// ...
}
If a is, read as a binary number string, a prefix of b, then set *c to be the rest of b (i.e. "what b has more than a") and return true. Otherwise, return false. Assume that binary strings always start with "1".
Of course - it is easy to do by comparing bit by bit (leftshift b until b==a). But is there a solution which is more efficient, without iterating over the bits?
Example: a=100 (4), b=1001 (9). Now set *c to 1.
You can use your favorite "fast" method to find the highest set bit. Let's call the function msb().
bool is_prefix (int a, int b, int *c) {
if (a == 0 || b == 0 || c == 0) return false;
int d = msb(b) - msb(a);
if (d < 0) return false;
if ((b >> d) == a) {
*c = b ^ (a << d);
return true;
}
return false;
}
Shift b so its high order bit aligns with a, and compare that with a. If they are equal, then a is a "prefix" of b.
This algorithm's performance depends on the performance of msb(). If it is constant, then this algorithm is constant. If msb() is expensive, then the "easy approach" may be the fastest approach.
I'm not too sure, but would something like the following work:
bool
is_prefix( unsigned a, unsigned b, unsigned* c )
{
unsigned mask = -1;
while ( mask != 0 && a != (b & mask) ) {
a <<= 1;
mask <<= 1;
}
c = b & ~mask;
return mask != 0;
}
(Just off the top of my head, so there could be errors.)