Java: get greatest common divisor - java

I have seen that such a function exists for BigInteger, i.e. BigInteger#gcd. Are there other functions in Java which also work for other types (int, long or Integer)? It seems this would make sense as java.lang.Math.gcd (with all kinds of overloads) but it is not there. Is it somewhere else?
(Don't confuse this question with "how do I implement this myself", please!)

As far as I know, there isn't any built-in method for primitives. But something as simple as this should do the trick:
public int gcd(int a, int b) {
if (b==0) return a;
return gcd(b,a%b);
}
You can also one-line it if you're into that sort of thing:
public int gcd(int a, int b) { return b==0 ? a : gcd(b, a%b); }
It should be noted that there is absolutely no difference between the two as they compile to the same byte code.

For int and long, as primitives, not really. For Integer, it is possible someone wrote one.
Given that BigInteger is a (mathematical/functional) superset of int, Integer, long, and Long, if you need to use these types, convert them to a BigInteger, do the GCD, and convert the result back.
private static int gcdThing(int a, int b) {
BigInteger b1 = BigInteger.valueOf(a);
BigInteger b2 = BigInteger.valueOf(b);
BigInteger gcd = b1.gcd(b2);
return gcd.intValue();
}

Or the Euclidean algorithm for calculating the GCD...
public int egcd(int a, int b) {
if (a == 0)
return b;
while (b != 0) {
if (a > b)
a = a - b;
else
b = b - a;
}
return a;
}

Unless I have Guava, I define like this:
int gcd(int a, int b) {
return a == 0 ? b : gcd(b % a, a);
}

Use Guava LongMath.gcd() and IntMath.gcd()

Jakarta Commons Math has exactly that.
ArithmeticUtils.gcd(int p, int q)

You can use this implementation of Binary GCD algorithm
public class BinaryGCD {
public static int gcd(int p, int q) {
if (q == 0) return p;
if (p == 0) return q;
// p and q even
if ((p & 1) == 0 && (q & 1) == 0) return gcd(p >> 1, q >> 1) << 1;
// p is even, q is odd
else if ((p & 1) == 0) return gcd(p >> 1, q);
// p is odd, q is even
else if ((q & 1) == 0) return gcd(p, q >> 1);
// p and q odd, p >= q
else if (p >= q) return gcd((p-q) >> 1, q);
// p and q odd, p < q
else return gcd(p, (q-p) >> 1);
}
public static void main(String[] args) {
int p = Integer.parseInt(args[0]);
int q = Integer.parseInt(args[1]);
System.out.println("gcd(" + p + ", " + q + ") = " + gcd(p, q));
}
}
From http://introcs.cs.princeton.edu/java/23recursion/BinaryGCD.java.html

Some implementations here are not working correctly if both numbers are negative. gcd(-12, -18) is 6, not -6.
So an absolute value should be returned, something like
public static int gcd(int a, int b) {
if (b == 0) {
return Math.abs(a);
}
return gcd(b, a % b);
}

we can use recursive function for find gcd
public class Test
{
static int gcd(int a, int b)
{
// Everything divides 0
if (a == 0 || b == 0)
return 0;
// base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a-b, b);
return gcd(a, b-a);
}
// Driver method
public static void main(String[] args)
{
int a = 98, b = 56;
System.out.println("GCD of " + a +" and " + b + " is " + gcd(a, b));
}
}

public int gcd(int num1, int num2) {
int max = Math.abs(num1);
int min = Math.abs(num2);
while (max > 0) {
if (max < min) {
int x = max;
max = min;
min = x;
}
max %= min;
}
return min;
}
This method uses the Euclid’s algorithm to get the "Greatest Common Divisor" of two integers. It receives two integers and returns the gcd of them. just that easy!

If you are using Java 1.5 or later then this is an iterative binary GCD algorithm which uses Integer.numberOfTrailingZeros() to reduce the number of checks and iterations required.
public class Utils {
public static final int gcd( int a, int b ){
// Deal with the degenerate case where values are Integer.MIN_VALUE
// since -Integer.MIN_VALUE = Integer.MAX_VALUE+1
if ( a == Integer.MIN_VALUE )
{
if ( b == Integer.MIN_VALUE )
throw new IllegalArgumentException( "gcd() is greater than Integer.MAX_VALUE" );
return 1 << Integer.numberOfTrailingZeros( Math.abs(b) );
}
if ( b == Integer.MIN_VALUE )
return 1 << Integer.numberOfTrailingZeros( Math.abs(a) );
a = Math.abs(a);
b = Math.abs(b);
if ( a == 0 ) return b;
if ( b == 0 ) return a;
int factorsOfTwoInA = Integer.numberOfTrailingZeros(a),
factorsOfTwoInB = Integer.numberOfTrailingZeros(b),
commonFactorsOfTwo = Math.min(factorsOfTwoInA,factorsOfTwoInB);
a >>= factorsOfTwoInA;
b >>= factorsOfTwoInB;
while(a != b){
if ( a > b ) {
a = (a - b);
a >>= Integer.numberOfTrailingZeros( a );
} else {
b = (b - a);
b >>= Integer.numberOfTrailingZeros( b );
}
}
return a << commonFactorsOfTwo;
}
}
Unit test:
import java.math.BigInteger;
import org.junit.Test;
import static org.junit.Assert.*;
public class UtilsTest {
#Test
public void gcdUpToOneThousand(){
for ( int x = -1000; x <= 1000; ++x )
for ( int y = -1000; y <= 1000; ++y )
{
int gcd = Utils.gcd(x, y);
int expected = BigInteger.valueOf(x).gcd(BigInteger.valueOf(y)).intValue();
assertEquals( expected, gcd );
}
}
#Test
public void gcdMinValue(){
for ( int x = 0; x < Integer.SIZE-1; x++ ){
int gcd = Utils.gcd(Integer.MIN_VALUE,1<<x);
int expected = BigInteger.valueOf(Integer.MIN_VALUE).gcd(BigInteger.valueOf(1<<x)).intValue();
assertEquals( expected, gcd );
}
}
}

Is it somewhere else?
Apache! - it has both gcd and lcm, so cool!
However, due to profoundness of their implementation, it's slower compared to simple hand-written version (if it matters).

/*
import scanner and instantiate scanner class;
declare your method with two parameters
declare a third variable;
set condition;
swap the parameter values if condition is met;
set second conditon based on result of first condition;
divide and assign remainder to the third variable;
swap the result;
in the main method, allow for user input;
Call the method;
*/
public class gcf {
public static void main (String[]args){//start of main method
Scanner input = new Scanner (System.in);//allow for user input
System.out.println("Please enter the first integer: ");//prompt
int a = input.nextInt();//initial user input
System.out.println("Please enter a second interger: ");//prompt
int b = input.nextInt();//second user input
Divide(a,b);//call method
}
public static void Divide(int a, int b) {//start of your method
int temp;
// making a greater than b
if (b > a) {
temp = a;
a = b;
b = temp;
}
while (b !=0) {
// gcd of b and a%b
temp = a%b;
// always make a greater than b
a =b;
b =temp;
}
System.out.println(a);//print to console
}
}

I used this method that I created when I was 14 years old.
public static int gcd (int a, int b) {
int s = 1;
int ia = Math.abs(a);//<-- turns to absolute value
int ib = Math.abs(b);
if (a == b) {
s = a;
}else {
while (ib != ia) {
if (ib > ia) {
s = ib - ia;
ib = s;
}else {
s = ia - ib;
ia = s;
}
}
}
return s;
}

Those GCD functions provided by Commons-Math and Guava have some differences.
Commons-Math throws an ArithematicException.class only for Integer.MIN_VALUE or Long.MIN_VALUE.
Otherwise, handles the value as an absolute value.
Guava throws an IllegalArgumentException.class for any negative values.

The % going to give us the gcd Between two numbers, it means:-
% or mod of big_number/small_number are =gcd,
and we write it on java like this big_number % small_number.
EX1: for two integers
public static int gcd(int x1,int x2)
{
if(x1>x2)
{
if(x2!=0)
{
if(x1%x2==0)
return x2;
return x1%x2;
}
return x1;
}
else if(x1!=0)
{
if(x2%x1==0)
return x1;
return x2%x1;
}
return x2;
}
EX2: for three integers
public static int gcd(int x1,int x2,int x3)
{
int m,t;
if(x1>x2)
t=x1;
t=x2;
if(t>x3)
m=t;
m=x3;
for(int i=m;i>=1;i--)
{
if(x1%i==0 && x2%i==0 && x3%i==0)
{
return i;
}
}
return 1;
}

Related

Greatest Common Divisor Challenge(Euclidean Algorithm)

everyone I've tried to solve the Greatest Common Divisor and it seem running well but i think its long code and I'm new to java and i need some advice what can i improve with the code.
public static void main(String[] args) {
System.out.println(GCD(888,54));
}
public static int GCD(int a, int b){
int r = a % b;
if(r != 0){
int rem = b % r;
if (rem > 10){
int aRem = r % rem;
if (aRem < 10){
return aRem;
}else {
int bRem = rem % aRem;
return bRem;
}
}else {
return rem;
}
}else {
return r;
}
}
}
You can do this using recursion as well.
Try using this code in your method.
public static int GCD(int a, int b){
if(b == 0){
return a;
}
return GCD(b, a%b);
}
The iterative way of implementing GCD in Java is the following:
public static int GCD(int a, int b) {
while (b != 0) {
int temp = a;
a = b;
b = temp%b;
}
return a;
}
This is an alternative to the recursive solution from Peter. The advantage is, that is won't use Stack space that much. It has the same time complexity but better memory complexity (O(1)) and will work for all valid data not risking the StackOverflowError.
You can just do using a for loop.
Sample code.
public static int GCD(int a, int b){
int gcd = 1;
for(int i = 1; i <= a && i <= b; i++){
if(a%i==0 && b%i==0)
gcd = i;
}
return gcd;
}

recursive horner scheme java

I am trying to program a recursive horner sheme.
At the moment it outputs the correct numbers, but in the wrong order (reversed).
However the output shall be onwards.
Any hints?
public class uhs {
public static void main (String[] args) {
int z = Integer.parseInt(args[0]);
int q = Integer.parseInt(args[1]);
hornerUmkehrungRekursiv(z, q);
System.out.println("");
}
static int hornerUmkehrungRekursiv(int z, int q) {
if (z == 0) {
return 0;
} else {
System.out.print(z % q);
return (hornerUmkehrungRekursiv(z / q, q) * 2) + z % q;
}
}
}
If You cannot use a StringBuilder variable, then You need to change Your code so that it makes recursive calls untill the last division, and then it prints the remainders. You just need to change Your code a bit, here is an example of how it can be done:
public class uhs {
public static void main(String[] args) {
int z = Integer.parseInt(args[0]);
int q = Integer.parseInt(args[1]);
System.out.println(hornerUmkehrungRekursiv(z, q));
}
static int hornerUmkehrungRekursiv(int z, int q) {
if (z / q != 0) {
System.out.print(hornerUmkehrungRekursiv(z / q, q));
}
return z % q;
}
}
You need to execute print after the recursive call:
static int hornerUmkehrungRekursiv(int z, int q) {
if (z == 0) {
return 0;
} else {
int v = z % q;
int r = (hornerUmkehrungRekursiv(z / q, q) * 2) + v;
System.out.print(v);
return r;
}
}
that gives you the expected result "11010010".

3 numbers in ascending order WITHOUT the use of conditional statements in Java. As in I can't use if statements at all

My code looks like this so far:
public class ThreeSort {
public static void main(String[] args) {
int num1 = Integer.parseInt(args[0]);
int num2 = Integer.parseInt(args[1]);
int num3 = Integer.parseInt(args[2]);
int x = Math.min(num1, num2);
int min = Math.min(x,num3);
int z = Math.max(num1, num2);
int max = Math.max(z, num3);
int a = 0;
int mid = 0;
while (mid >= min && mid <= max) {
mid = a;
}
System.out.println(min);
System.out.println(a);
System.out.println(max);
}
I know how to do the min and the max but I'm having troubles with the middle one. Any idea how to do that without conditional statements?
in this case there is a simple algorithm for it:
mid = Math.max(Math.min(num1,num2), Math.min(Math.max(num1,num2),num3));
Also as the operator ^ denotes bitwise xor. so another way is:
mid=num1^num2^num3^max^min;
EXAMPLE:
public static void main(String[] args) {
System.out.println(mid(70, 3, 10));
}
static int mid(int a, int b, int c) {
int mx = Math.max(Math.max(a, b), c);
int mn = Math.min(Math.min(a, b), c);
int md = a ^ b ^ c ^ mx ^ mn;
return md;
}
OUTPUT: 10.
Also as OldCurmudgeon said below you can calculate the mid with below formula:
int mid = num1 + num2 + num3 - min - max;
Put them in a List and sort it...
List<Integer> ints = new LinkedList<>();
ints.add(Integer.parseInt(args[0]));
ints.add(Integer.parseInt(args[1]));
ints.add(Integer.parseInt(args[2]));
Collections.sort(ints); // smallest -> greatest
System.out.println(ints);
Collections.reverse(ints); // greatest -> smallest
System.out.println(ints);
int mid = num1 + num2 + num3 - min - max;
Sorry for briefness - posted from my phone.
It must be self-evident that the middle number is the sum of the three numbers minus the max minus the min. Would also work if max == mid or max == min or even both.
Assuming this is some kind of puzzle/homework are you allowed to use the ternary operator?
int[] ints = {3, 1, 2};
int min = ints[0] <= ints[1] && ints[0] <= ints[2]
? ints[0]
: ints[1] <= ints[0] && ints[1] <= ints[2]
? ints[1]
: ints[2];
This is how I would implement three_sort without any if statements or ternary operators. You would have to adapt this to your language of choice.
def two_sort(a, b):
small = int(a < b) * a + int(a >= b) * b
large = int(a >= b) * a + int(a < b) * b
return small, large
def three_sort(a, b, c):
a, b = two_sort(a, b)
a, c = two_sort(a, c)
b, c = two_sort(b, c)
return a, b, c
for a more general solution:
from random import randint
def two_sort(a, b):
small = int(a < b) * a + int(a >= b) * b
large = int(a >= b) * a + int(a < b) * b
return small, large
return li[-1]
def n_sort(li):
for _ in li:
for i, _ in enumerate(li[:-1]):
li[i], li[i+1] = two_sort(li[i], li[i+1])
return li
N = 10
li = [randint(0, 1000) for _ in range(N)]
print(N_Sort(N)(*li))
public class ThreeSort {
public static void main(String[] args) {
// command-line input
int a = Integer.parseInt(args[0]);
int b= Integer.parseInt(args[1]);
int c = Integer.parseInt(args[2]);
// compute the order
int max=Math.max(Math.max(a,b),c);
int min =Math.min(Math.min(a,b ), c);
int middle = a + b + c - max - min;
// output in ascending order
System.out.println(min+"\n" + middle+ "\n"+ max);
}
}

Implementing RSA algorithm

I had the task to implement RSA algorithm, I read about it in Cormen's book and got most of information from there. I thought it worked good until I faced large p and q primes. For numbers about 250 and lower encryption and decryption works good, however if they are larger, modular exponentation returns negative numbers, which doesn't make sense.
I know that encrypted number can't be larger than n. I read that I can also compute inverse modulo by using extended GCD algorithm and taking x as that value, but when I tried calling extendedEuclid(phi, e)[1] it returned different values than function in RSA class. How can I fix it ?
Here is code for all needed components to compute keys.
Euclid Algorithm
public class Euclid {
public static int euclid(int a, int b) {
if (a < b) {
int tmp = a;
a = b;
b = tmp;
}
if (b == 0) {
return a;
} else {
return euclid(b, a % b);
}
}
public static int[] extendedEuclid(int a, int b) {
if (a < b) {
int tmp = a;
a = b;
b = tmp;
}
if (b == 0) {
return new int[]{a, 1, 0};
} else {
int vals[] = extendedEuclid(b, a % b);
int d = vals[0];
int x = vals[2];
int y = vals[1] - (int) Math.floor(a / b) * vals[2];
return new int[]{d, x, y};
}
}
}
Modular Exponentation
public class Modular {
public static int modularExponentation(int a, int b, int n) {
int c = 0;
int d = 1;
String binaryString = Integer.toBinaryString(b);
for (int i = 0; i < binaryString.length(); i++) {
c = 2 * c;
d = (d * d) % n;
if (binaryString.charAt(i) == '1') {
c = c + 1;
d = (d * a) % n;
}
}
return d;
}
}
RSA generator
public class RsaKeyGenerator {
int d;
int e;
int n;
public RsaKeyGenerator() {
int p = 827;
int q = 907;
n = p * q;
int phi = (p - 1) * (q - 1);
e = computeCoPrime(phi);
d = invMod(e, phi);
System.out.println("Public: " + e);
System.out.println("Private: " + d);
}
private static int computeCoPrime(int phi) {
int e = 2;
while (Euclid.euclid(e, phi) != 1) {
e++;
}
return e;
}
private int invMod(int a, int n) {
int a0, n0, p0, p1, q, r, t;
p0 = 0;
p1 = 1;
a0 = a;
n0 = n;
q = n0 / a0;
r = n0 % a0;
while (r > 0) {
t = p0 - q * p1;
if (t >= 0) {
t = t % n;
} else {
t = n - ((-t) % n);
}
p0 = p1;
p1 = t;
n0 = a0;
a0 = r;
q = n0 / a0;
r = n0 % a0;
}
return p1;
}
public int encrypt(int num) {
return Modular.modularExponentation(num, e, n);
}
public int decrypt(int cipher) {
return Modular.modularExponentation(cipher, d, n);
}
public static void main(String[] args) {
RsaKeyGenerator rsa = new RsaKeyGenerator();
int cip = rsa.encrypt(1343);
System.out.println(cip);
System.out.println(rsa.decrypt(cip));
}
}
The problem you're facing is integer overflow so if you're trying to store a number higher than 2^31 -1 in a signed integer which just isn't possible. So what ends up happening when you hit that limit is that the number wraps around to -2^31 -1.
What you want to do is look into the BigInteger class which will let you store much bigger numbers and should work fine.
The integer overflow happens at this line in the ModularExponentiation class:
d = (d * a) % n;

How to write a simple Java program that finds the greatest common divisor between two numbers? [duplicate]

This question already has answers here:
How to find GCD, LCM on a set of numbers
(13 answers)
Closed 8 years ago.
Here is the question:
"Write a method named gcd that accepts two integers as parameters and returns the greatest common divisor of the two numbers. The greatest common divisor (GCD) of two integers a and b is the largest integer that is a factor of both a and b. The GCD of any number and 1 is 1, and the GCD of any number and 0 is that number.
One efficient way to compute the GCD of two numbers is to use Euclid's algorithm, which states the following:
GCD(A, B) = GCD(B, A % B)
GCD(A, 0) = Absolute value of A"
I'm really confused as to how to solve this problem. I just want some hints and tips as to what I did wrong in the program I have so far. (I have to put in a Scanner, that is my teacher's requirement.)
Don't give me a full code as I kinda want to solve this out myself. Maybe just give me a hint on how I incorporate this formula that you see above. (And if you're wondering why I put in the == 0, it's because I thought that if you have two numbers, say 0 and 90, their GCD would be 0 right??)
Also, my code has to include while loops...I would've preferred if loops...
Thanks in advance! :)
My current program:
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
int a = console.nextInt();
int b = console.nextInt();
gcd (a, b);
}
public static void gcd(int a, int b) {
System.out.print("Type in two numbers and I will print outs its Greatest Common Divisor: ");
int gcdNum1 = console.nextInt();
int gcdNum2 = console.nextInt();
while (gcdNum1 == 0) {
gcdNum1 = 0;
}
while (gcdNum2 > gcdNum1) {
int gcd = gcdNum1 % gcdNum2;
}
System.out.print(gcdNum1 + gcdNum2);
}
}
A recursive method would be:
static int gcd(int a, int b)
{
if(a == 0 || b == 0) return a+b; // base case
return gcd(b,a%b);
}
Using a while loop:
static int gcd(int a, int b)
{
while(a!=0 && b!=0) // until either one of them is 0
{
int c = b;
b = a%b;
a = c;
}
return a+b; // either one is 0, so return the non-zero value
}
When I'm returning a+b, I'm actually returning the non-zero number assuming one of them is 0.
You can also do it in a three line method:
public static int gcd(int x, int y){
return (y == 0) ? x : gcd(y, x % y);
}
Here, if y = 0, x is returned. Otherwise, the gcd method is called again, with different parameter values.
public static int GCD(int x, int y) {
int r;
while (y!=0) {
r = x%y;
x = y;
y = r;
}
return x;
}
import java.util.Scanner;
public class Main {
public static void main(String [] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Please enter the first integer:");
int b = input.nextInt();
System.out.println("Please enter the second integer:");
int d = input.nextInt();
System.out.println("The GCD of " + b + " and " + d + " is " + getGcd(b,d) + ".");
}
public static int getGcd(int b, int d)
{
int gcd = 1;
if(b>d)
{
for(int i = d; i >=1; i--)
{
if(b%i==0 && d%i ==0)
{
return i;
}
}
}
else
{
for(int j = b; j >=1; j--)
{
if(b%j==0 && d% j==0)
{
return j;
}
}
}
return gcd;
}
}
One way to do it is the code below:
int gcd = 0;
while (gcdNum2 !=0 && gcdNum1 != 0 ) {
if(gcdNum1 % gcdNum2 == 0){
gcd = gcdNum2;
}
int aux = gcdNum2;
gcdNum2 = gcdNum1 % gcdNum2;
gcdNum1 = aux;
}
You do not need recursion to do this.
And be careful, it says that when a number is zero, then the GCD is the number that is not zero.
while (gcdNum1 == 0) {
gcdNum1 = 0;
}
You should modify this to fulfill the requirement.
I am not going to tell you how to modify your code entirely, only how to calculate the gcd.
private static void GCD(int a, int b) {
int temp;
// make a greater than b
if (b > a) {
temp = a;
a = b;
b = temp;
}
while (b !=0) {
// gcd of b and a%b
temp = a%b;
// always make a greater than bf
a =b;
b =temp;
}
System.out.println(a);
}
import java.util.Scanner;
class CalculateGCD
{
public static int calGCD(int a, int b)
{
int c=0,d=0;
if(a>b){c=b;}
else{c=a;}
for(int i=c; i>0; i--)
{
if(((a%i)+(b%i))==0)
{
d=i;
break;
}
}
return d;
}
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
System.out.println("Enter the nos whose GCD is to be calculated:");
int a=sc.nextInt();
int b=sc.nextInt();
System.out.println(calGCD(a,b));
}
}
Now, I just started programing about a week ago, so nothing fancy, but I had this as a problem and came up with this, which may be easier for people who are just getting into programing to understand. It uses Euclid's method like in previous examples.
public class GCD {
public static void main(String[] args){
int x = Math.max(Integer.parseInt(args[0]),Integer.parseInt(args[1]));
int y = Math.min(Integer.parseInt(args[0]),Integer.parseInt(args[1]));
for (int r = x % y; r != 0; r = x % y){
x = y;
y = r;
}
System.out.println(y);
}
}

Categories

Resources