2

Suppose n, a, b are positive integers where n is not a prime number, such that n=ab with a≥b and (a−b) is small as possible. What would be the best algorithm to find the values of a and b if n is given?

I read a solution where they try to represent n as the difference between two squares via searching for a square S bigger than n such that S - n = (another square). Why would that be better than simply finding the prime factors of n and searching for the combination where a,b are factors of n and a - b is minimized?

2 Answers2

3

Firstly....to answer why your approach

simply finding the prime factors of n and searching for the combination where a,b are factors of n and a - b is minimized

is not optimal:

Suppose your number is n = 2^7 * 3^4 * 5^2 * 7 * 11 * 13 (=259459200), well within range of int. From the combinatorics theory, this number has exactly (8 * 5 * 3 * 2 * 2 * 2 = 960) factors. So, firstly you find all of these 960 factors, then find all pairs (a,b) such that a * b = n, which in this case will be (6C1 + 9C2 + 11C3 + 13C4 + 14C5 + 15C6 + 16C7 + 16C8) ways. (if I'm not wrong, my combinatorics is a bit weak). This is of the order 1e5 if implemented optimally. Also, implementation of this approach is hard.

Now, why the difference of squares approach

represent S - n = Q, such that S and Q are perfect squares

is good:

This is because if you can represent S - n = Q, this implies, n = S - Q

=> n = s^2 - q^2
=> n = (s+q)(s-q)
=> Your reqd ans = 2 * q

Now, even if you iterate for all squares, you will either find your answer or terminate when difference of 2 consecutive squares is greater than n

But I don't think this will be doable for all n (eg. if n=6, there is no solution for (S,Q).)

Another approach:

Iterate from floor(sqrt(n)) to 1. The first number (say, x), such that x|n will be one of the numbers in the required pair (a,b). Other will be, obvs, y = x/n. So, your answer will be y - x.

This is O(sqrt(n)) time complex algorithm.

vish4071
  • 5,135
  • 4
  • 35
  • 65
  • Excellent summary, I couldn't have done it better! However, it is *certain fact* that the square approach cannot find any pairs with odd differences - as can be seen from the example that you gave. There is no 'I don't think' uncertainty about it. One option is to admit halves in addition to integers, so that odd-differenced pairs are covered as well. – DarthGizka May 04 '16 at 10:57
  • The question does not mention that a and b are supposed to be prime, but the title suggests it. This means that the difference between a and b must be even unless one of the two is the only even prime; this in turn means that the square method is applicable without restriction, provided that even `n` are handled specially. – DarthGizka May 04 '16 at 11:22
  • I don't think `(a,b)` are supposed to be prime. There is no line which says `n` is a product of two primes. (coz otherwise, it is not even possible) – vish4071 May 04 '16 at 12:00
  • And if that is the case, it will be much easier to find all primes till `1e5` using Erastothenes Sieve, and find that prime factor which will obvs be the part of answer. (This will work nice if OP has many test cases to solve) – vish4071 May 04 '16 at 12:13
2

A general method could be this:

  • Find the prime factorization of your number: n = Π pi ai. Except for the worst cases where n is prime or semiprime, this will be substantially faster than O(n1/2) time of the iteration down from the square root, which won't divide the found factors out of the number.

    Recall that the simplest, trial division, prime factorization is done by repeatedly trying to divide the number by increasing odd numbers (or by primes) below the number's square root, dividing out of the number each factor -- thus prime by construction -- as it is found (n := n/f).

  • Then, lazily enumerate the factors of n in order from its prime factorization. Stop after producing half of them. Having thus found n's (not necessarily prime) factor that is closest to its square root, find the second factor by simple division.

In case this must repeatedly run many times, it will greatly pay out to precalculate the needed primes below the n's square root, to use in the factorizations.

Community
  • 1
  • 1
Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • Yeah...but the upper bound in this case is also `sqrt(n)`, coz, finding all prime factors in itself is `O(sqrt(n))` work – vish4071 May 05 '16 at 06:40
  • @vish4071 no, it is so only in worst case of prime or semiprime, because the found factor is divided out of the number `n` being factorized, `n = n/f`, so the upper bound becomes less and less with each found factor. In case of 259459200 it will work only until 11, not 16107. – Will Ness May 05 '16 at 09:10
  • This is an outstanding answer. I followed the trail to your answer to factorizing 600851475143, and sqrt(600851475143) is orders of magnitude larger than 1473. Very counterintuitive indeed to think factorization is the way. I suppose best way to understand the difference is that SQRT(n) is the upper bound of doing the prime sieve and will be the worst case scenario(RSA numbers, etc). THANKS –  May 08 '16 at 21:53
  • I agree with @WillNess there...This is indeed a good approach. Average running time will be much slower. Nice answer. – vish4071 May 09 '16 at 07:11