GCD function in c++ sans cmath library - c++

I'm writing a mixed numeral class and need a quick and easy 'greatest common divisor' function. Can anyone give me the code or a link to the code?

The libstdc++ algorithm library has a hidden gcd function (I'm using g++ 4.6.3).
#include <iostream>
#include <algorithm>
int main()
{
std::cout << std::__gcd(100,24); // print 4
return 0;
}
You are welcome :)
UPDATE: As #chema989 noted it, in C++17 there is std::gcd() function available with <numeric> header.

I'm tempted to vote to close -- it seems difficult to believe that an implementation would be hard to find, but who knows for sure.
template <typename Number>
Number GCD(Number u, Number v) {
while (v != 0) {
Number r = u % v;
u = v;
v = r;
}
return u;
}
In C++ 17 or newer, you can just #include <numeric>, and use std::gcd (and if you care about the gcd, chances are pretty fair that you'll be interested in the std::lcm that was added as well).

A quick recursive version:
unsigned int gcd (unsigned int n1, unsigned int n2) {
return (n2 == 0) ? n1 : gcd (n2, n1 % n2);
}
or the equivalent iterative version if you're violently opposed to recursion (a):
unsigned int gcd (unsigned int n1, unsigned int n2) {
unsigned int tmp;
while (n2 != 0) {
tmp = n1;
n1 = n2;
n2 = tmp % n2;
}
return n1;
}
Just substitute in your own data type, zero comparison, assignment and modulus method (if you're using some non-basic type like a bignum class, for example).
This function actually came from an earlier answer of mine for working out integral aspect ratios for screen sizes but the original source was the Euclidean algorithm I learnt a long time ago, detailed here on Wikipedia if you want to know the math behind it.
(a) The problem with some recursive solutions is that they approach the answer so slowly you tend to run out of stack space before you get there, such as with the very badly thought out (pseudo-code):
def sum (a:unsigned, b:unsigned):
if b == 0: return a
return sum (a + 1, b - 1)
You'll find that very expensive on something like sum (1, 1000000000) as you (try to) use up a billion or so stack frames. The ideal use case for recursion is something like a binary search where you reduce the solution space by half for each iteration. The greatest common divisor is also one where the solution space reduces rapidly so fears about massive stack use are unfounded there.

For C++17 you can use std::gcd defined in header <numeric>:
auto res = std::gcd(10, 20);

The Euclidean algorithm is quite easy to write in C.
int gcd(int a, int b) {
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}

Related

Wrong answer due to precision issues?

I am implementing Greedy Approach to TSP:
Start from first node.
Go to nearest node not visited yet. (If multiple, go to the one with the lowest index.)
Don't forget to include distance from node 1 to last node visited.
However, my code gives the wrong answer. I implemented the same code in Python and the python code gives right answer.
In my problem, the nodes are coordinates on 2-D plane and the distance is the Euclidean Distance.
I even changed everything to long double because it's more precise.
In fact, if I reverse the order of the for loop to reverse the direction and add an additional if statement to handle ties (we want minimum index nearest node), it gives a very different answer.
Is this because of precision issues?
(Note: I have to print floor(ans))
INPUT: Link
EXPECTED OUTPUT: 1203406
ACTUAL OUTPUT: 1200403
#include <iostream>
#include <cmath>
#include <vector>
#include <cassert>
#include <functional>
using namespace std;
int main() {
freopen("input.txt", "r", stdin);
int n;
cin >> n;
vector<pair<long double, long double>> points(n);
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
assert(x == i + 1);
cin >> points[i].first >> points[i].second;
}
// Returns the squared Euclidean Distance
function<long double(int, int)> dis = [&](int x, int y) {
long double ans = (points[x].first - points[y].first) * (points[x].first - points[y].first);
ans += (points[x].second - points[y].second) * (points[x].second - points[y].second);
return ans;
};
long double ans = 0;
int last = 0;
int cnt = n - 1;
vector<int> taken(n, 0);
taken[0] = 1;
while (cnt > 0) {
pair<long double, int> mn = {1e18, 1e9};
for (int i = 0; i < n; ++i) {
if (!taken[i]) {
mn = min(mn, {dis(i, last), i});
}
}
int nex = mn.second;
taken[nex] = 1;
cnt--;
ans += sqrt(mn.first);
last = nex;
}
ans += sqrt(dis(0, last));
cout << ans << '\n';
return 0;
}
UPD: Python Code:
import math
file = open("input.txt", "r")
n = int(file.readline())
a = []
for i in range(n):
data = file.readline().split(" ")
a.append([float(data[1]), float(data[2])])
for c in a:
print(c)
def dis(x, y):
cur_ans = (a[x][0] - a[y][0]) * (a[x][0] - a[y][0])
cur_ans += (a[x][1] - a[y][1]) * (a[x][1] - a[y][1])
cur_ans = math.sqrt(cur_ans)
return cur_ans
ans = 0.0
last = 0
cnt = n - 1
take = []
for i in range(n):
take.append(0)
take[0] = 1
while cnt > 0:
idx = -1
cur_dis = 1e18
for i in range(n):
if take[i] == 0:
if dis(i, last) < cur_dis:
cur_dis = dis(i, last)
idx = i
assert(idx != -1)
take[idx] = 1
cnt -= 1
ans += cur_dis
last = idx
ans += dis(0, last)
print(ans)
file.close()
# 1203406
Yes, the difference is due to round-off error, with the C++ code producing the more accurate result because of your use of long double. If you change your C++ code, such that it uses the same precision as Python (IEEE-754, meaning double precision) you get the exact same round-off errors in both codes. Here is a demonstrator in Godbolt Compiler explorer, with your example boiled down to 4000 points: https://godbolt.org/z/rddrdT54n
If I run the same code on the whole input file I get 1203406.5012708856 in C++ and in Python (Had to try this offline, because Godbolt understandibly killed the process).
Note, that in theory your Python-Code and C++ code are not completely analogous, because std::min will compare tuples and pairs lexicographically. So if you ever have two distances exactly equal, the std::min call will choose the smaller of the two indices. Practically, this does not make a difference, though.
Now I don't think you really can get rid off the rounding errors. There are a few tricks to minimize them.
using higher precision (long double) is one option. But this also makes your code slower, it's a tradeoff
Rescale your points, so that they are relative to the centroid of all points, and the unit reflects your problem (e.g. don't think in mm, miles, km or whatever, but rather in "variance of your data set"). You can't get rid of numerical cancellation in your calculation of the Euclidean distance, but if the relative distances are small compared to the absolute values of the coordinates, the cancellation is typically more severe. Here is a small demonstration:
#include <iostream>
#include <iomanip>
int main() {
std::cout
<< std::setprecision(17)
<< (1000.0001 - 1000)/0.0001
<< std::endl
<< (1.0001 - 1)/0.0001
<< std::endl;
return 0;
}
0.99999999974897946
0.99999999999988987
Finally, there are some tricks and algorithms to better control the error accumulation in large sums (https://en.wikipedia.org/wiki/Pairwise_summation, https://en.wikipedia.org/wiki/Kahan_summation_algorithm)
One final comment, a bit unrelated to your question: Use auto with lambdas, i.e.
auto dis = [&](int x, int y) {
// ...
};
C++ has many different kinds of callable objects (functions, function pointers, functors, lambdas, ...) and std::function is a useful wrapper to have one type representing all kinds of callables with the same signature. This comes at some computational overhead (runtime polymorphism, type erasure) and the compiler will have a hard time optimizing your code. So if you don't need the type erasing functionality of std::function, just store your lambda in a variable declared with auto.

Finding greatest power devisor using recursion?

The question asks me to find the greatest power devisor of (number, d) I found that the function will be like that:
number % d^x ==0
I've done so far using for loop:
int gratestDevisor(int num, int d){
int p = 0;
for(int i=0; i<=num; i++){
//num % d^i ==0
if( (num % (int)pow(d,i))==0 )
p=i;
}
return p;
}
I've tried so much converting my code to recursion, I can't imagine how to do it and I'm totally confused with recursion. could you give me a tip please, I'm not asking you to solve it for me, just some tip on how to convert it to recursion would be fine.
Here is a simple method with recursion. If ddivides num, you simply have to add 1 to the count, and divide num by d.
#include <stdio.h>
int greatestDevisor(int num, int d){
if (num%d) return 0;
return 1 + greatestDevisor (num/d, d);
}
int main() {
int num = 48;
int d = 2;
int ans = greatestDevisor (num, d);
printf ("%d\n", ans);
return 0;
}
A recursive function consist of one (or more) base case(es) and one (or more) calls to the function itself. The key insight is that each recursive call reduces the problem to something smaller till the base case(es) are reached. State (like partial solutions) are either carried in arguments and return value.
You asked for a hint so I am explicitly not providing a solution. Others have.
Recursive version (which sucks):
int powerDividing(int x, int y)
{
if (x % y) return 0;
return 1 + powerDividing(x/y, y);
}

How do I speed up this program to find fibonacci sequence

I am doing this coding question where they ask you to enter numbers N and M, and you are supposed to output the Nth fibonacci number mod M. My code runs rather slowly and I would like to learn how to speed it up.
#include<bits/stdc++.h>
using namespace std;
long long fib(long long N)
{
if (N <= 1)
return N;
return fib(N-1) + fib(N-2);
}
int main ()
{
long long N;
cin >> N;
long long M;
cin >> M;
long long b;
b = fib(N) % M;
cout << b;
getchar();
return 0;
}
While the program you wrote is pretty much the go-to example of recursion in education, it is really a pretty damn bad algorithm as you have found out. Try to write up the call tree for fib(7) and you will find that the number of calls you make balloons dramatically.
There are many ways of speeding it up and keeping it from recalculating the same values over and over. Somebody already linked to a bunch of algorithms in the comments - a simple loop can easily make it linear in N instead of exponential.
One problem with this though is that fibonacci numbers grow pretty fast: You can hold fib(93) in a 64 bit integer, but fib(94) overflows it.
However, you don't want the N'th fibonacci number - you want the N'th mod M. This changes the challenge a bit, because as long as M is smaller than MAX_INT_64 / 2 then you can calculate fib(N) mod M for any N.
Turn your attention to Modular arithmetic and the congruence relations. Specifically the one for addition, which says (changed to C++ syntax and simplified a bit):
If a1 % m == b1 and a2 % m == b2 then (a1 + a2) % m == (b1 + b2) % m
Or, to give an example: 17 % 3 == 2, 22 % 3 == 1 => (17 + 22) % 3 == (2 + 1) % 3 == 3 % 3 == 0
This means that you can put the modulo operator into the middle of your algorithm so that you never add big numbers together and never overflow. This way you can easily calculate f.ex. fib(10000) mod 237.
There is one simple optimatimization in calling fib without calculating duplicate values. Also using loops instead of recursion may speed up the process:
int fib(int N) {
int f0 = 0;
int f1 = 1;
for (int i = 0; i < N; i++) {
int tmp = f0 + f1;
f0 = f1;
f1 = tmp;
}
return f1;
}
You can apply the modulo operator sugested by #Frodyne on top of this.
1st observation is that you can turn the recursion into a simple loop:
#include <cstdint>
std::uint64_t fib(std::uint16_t n) {
if (!n)
return 0;
std::uint64_t result[]{ 0,1 };
bool select = 1;
for (auto i = 1; i < n; ++i , select=!select)
{
result[!select] += result[select];
};
return result[select];
};
next you can memoize it:
#include <cstdint>
#include <vector>
std::uint64_t fib(std::uint16_t n) {
static std::vector<std::uint64_t> result{0,1};
if (result.size()>n)
return result[n];
std::uint64_t back[]{ result.crbegin()[1],result.back() };
bool select = 1;
result.reserve(n + 1);
for (auto i=result.size(); i < result.capacity();++i, select = !select)
result.push_back(back[!select] += back[select]);
return result[n];
};
Another option would be an algebraic formula.
cheers,
FM.

Recursive call getting stuck

#include <bits/stdc++.h>
using namespace std;
int gcd(long long int a, long long int b){
if(a||b==0){
return 0;
}
else if(b==a){
return a;
}
else if(a>b){
return gcd(a-b,b);
}
else{
return gcd(a,b-a);
}
}
int lcm(long long int a,long long int b){
return a*b/(gcd(a,b));
}
int main(){
long long int answer=1;
for (int i = 2; i<=20; i++) {
answer=lcm(i,answer);
cout<<answer;
}
cout<<answer;
return 0;
}
i wrote this code for problem 5 in project euler. however the output screen is showing nothing and is getting hanged. i put a few debugging cout statements and i understood that in the main function the it is entering the loop but it is not continuing the excution after the call for lcm.
the program is to find the lcm of numbers from 1 to 20. i used the formula llcm= a*b/gcd(a,b). where in gcd also i used the recursive euclidian algorithm. i am not able to trace out the reason for this bug . could anyone help pls.
also if there any suggestions regarding my coding style (indentation, type casting, variable names, algorithm or anything) please point it out. i am beginner so i do not know much regarding c++ and programming styles.
Your program is becoming stuck because of this line:
if (a || b == 0) {
The == operator has higher precedence than ||, so the condition is in fact the same as:
if (a || (b == 0)) {
Which in C(++) is the same as:
if ((a != 0) || (b == 0)) {
That is, if a is non-zero OR b is zero. a will be non-zero straight away, hence your program will always try to divide by zero, which causes problems. I am not sure where you found this version of the algorithm, a cursory search results in a much simpler variant:
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, (a % b));
}
}
As for the second part of your question, there are many little (stylistic) issues in your code that I would change. Inconsistent spacing, unnecessary use of long long int (an int would do just fine here) … But for these, I recommend the codereview StackExchange.

Overflow while calculating combinations

I am trying to calculate the combination C(40, 20) in C++, however the data types in C++ seems unable to correctly handle this calculation even though I have used long long data type. The following is my code:
#include <iostream>
long long fac(int x) {
register long long i,f = 1; // Optimize with regFunction
for(i = 1;i <= x;i++)
f *= i;
std::cout << f << std::endl;
return f;
}
// C(n,r) = n!/r!(n-r)!
long long C(long long n, long long r) {
return fac(n) / (fac(r) * fac(n - r));
}
int main(int argc, char const *argv[]) {
std::cout << C(40, 20) << std::endl;
return 0;
}
Any idea to solve this problem?
Compute C at once by executing division immediately after multiplication:
long long C(long long n, long long r)
{
long long f = 1; // Optimize with regFunction
for(auto i = 0; i < r;i++)
f = (f * (n - i)) / (i + 1);
return f ;
}
Result should be exact (divisions without remainders, until overflows) since any integer factor present in (i+1) is already present in (n -i). (Should not be too difficult to prove)
Your numbers are growing too much and that is a common problem in this kind of calculations and I am afraid there is no straightforward solution. Even if you might reduce a bit the number of multiplications you will make probably still you will end up in an overflow with long long
You might want to check those out:
https://mattmccutchen.net/bigint/
https://gmplib.org/
I know there are different algorithmic approaches on this matter. I remember there were some solutions to use strings to store integer representations and stuff but as #Konrad mentioned this might be a poor approach to the matter.
The problem is that factorials get big very quickly. 40! is too large to be stored in a long long. Luckily you don’t actually need to compute this number here since you can reduce the fraction in the calculation of C(n, r) before computing it. This yields the equation (from Wikipedia):
This works much better since k! (r! in your code) is a much smaller number than n!. However, at some point it will also break down.
Alternatively, you can also use the recurrence definition by implementing a recursive algorithm. However, this will be very inefficient (exponential running time) unless you memoise intermediate results.
A lazy way out would be to use a library that supports multiple precision, for example GNU GMP.
Once you have installed it correctly (available from the repositories on most Linux distributions), it comes down to:
adding #include <gmpxx.h> to your source file
replacing long long with mpz_class
compiling with -lgmpxx -lgmp
The source:
#include <iostream>
#include <gmpxx.h>
mpz_class fac(mpz_class x) {
int i;
mpz_class f(1); // Optimize with regFunction
for(i = 1;i <= x;i++)
f *= i;
std::cout << f << std::endl;
return f;
}
// C(n,r) = n!/r!(n-r)!
mpz_class C(mpz_class n, mpz_class r) {
return fac(n) / (fac(r) * fac(n - r));
}
int main(int argc, char const *argv[]) {
std::cout << C(40, 20) << std::endl;
return 0;
}
Compiling and running:
$ g++ comb.cpp -lgmpxx -lgmp -o comb
$ ./comb
2432902008176640000
2432902008176640000
815915283247897734345611269596115894272000000000
137846528820
If you want to be thorough, you can do a lot more, but this will get you answers.
Even if you used uint64 aka ulonglong, the max value is 18446744073709551615 whereas 40! is 815915283247897734345611269596115894272000000000 which is a bit bigger.
I recommend you to use GMP for this kind of maths