-1

Problem: Given A,B print the number of pairs (a,b) such that GCD(a,b)=1 and 1<=a<=A and 1<=b<=B.

Solution (Brute Force Approach) In the below code, i have used brute force approach and it works fine. However the execution time is more 10 sec if A & B > 10^5

Alternative Solution From my research i found out that finding prime factors of A & B will reduce the execution time considerably (< 3 sec), but i'm not sure how to apply it.

Need Help: Can anyone help me to arrive at the result with < 3 sec execution time?

class GCD {
public static void main(String[] args) {
    int A = 0, B = 0, GCD = 0, count = 0;
    BigInteger B1, B2 = null;

    A = Integer.parseInt(args[0]);
    B = Integer.parseInt(args[1]);

    for (int a = 1; a <= A; a++) {
        for (int b = 1; b <= B; b++) {
            B1 = BigInteger.valueOf(a);
            B2 = BigInteger.valueOf(b);
            GCD = calculateGCD(B1, B2);
            if (GCD == 1) {
                count++;
            }
        }
    }
    System.out.println(count);
}

public static int calculateGCD(BigInteger number1, BigInteger number2) {
    return (number1.gcd(number2)).intValue();
}
}
  • here is an idea how to calculate the gcd efficiently: http://stackoverflow.com/questions/4885537/what-is-the-fastest-way-to-find-the-gcd-of-n-numbers – cruxi May 30 '14 at 10:00
  • 1
    Do you know how to find the prime factorization of a number? Start by writing a method `factor` that returns a `List` of the appropriate numeric type. Additionally, is using `BigInteger` required? It's a good bit slower than `long`. – chrylis -cautiouslyoptimistic- May 30 '14 at 10:02
  • Now i have 2 Lists which contains the prime factors of A and B. But im not sure how to proceed further with those prime factors. – user3690689 May 30 '14 at 13:58

1 Answers1

0

I do not want to write a complete programm or something, but I want to give you some tips for speeding up your program:

  1. gcd(a,b) = gcd(b,a) so only compute pairs (a, b) with a < b. gcd(a,a) = 1 holds only for a = 1. Also gcd(1,b) = 1 for all b, so you can start with a = 2 and a count = 1 + 2*(B-1).
  2. compute all primefactors for all 1 < a <= A at once by using something like the Sieve of Eratosthenes. E.g. every secound number contains primefactor 2, every third the primfactor 3.
  3. You do not need to compute the gcd. Let a contain the distinct primfactors p and q. Then you know:
    • There are B-a numbers to test.
    • Every p-th number contains also the primfactor p, every q-th primenumber also contains the primfactor q. floor( (B-a)/p ) numbers have a gcd >= p and floor( (B-a)/q ) numbers have a gcd >= q and floor( (B-a)/(p*q) ) numbers have you counted twice. So you can get the number of pairs (a,b) with a < b as
      (B-a) - floor( (B-a)/p ) - floor( (B-a)/q ) + floor( (B-a)/(p*q) )
    • if you want also the pairs it self, you can use a for-loop and jump every step where i (for-loop counter) is divisable by any primefactor of a

I think this should speed up your program as much as you need to reach less than a second.

AbcAeffchen
  • 14,400
  • 15
  • 47
  • 66