简体   繁体   中英

efficient algorithm for Pythagorean Triples in java

So I try to make a program using java. its input is integers, the integers are considered as the sum of 3 integers a, b and c ( a^2 + b^2 = c^2 ), its output is c^2. To do this, I expand the equation combine a^2 + b^2 - c^2 = 0 and c = sum - a - b , get Math.pow(sum, 2) - 2 * sum * (a + b) + 2 * a * b . Then I get a + b <= sum*2/3 then I substitute all the combination of a, b into the equation to see when it is zero.

Here is my code:

/** Pythagorean Triples
  * test case for small numbers
  * Tony
  */
import java.util.*;

public class Solution54 {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);


    int times = sc.nextInt();

    for (int i = 0; i < times; i++) {
      /* prompt the sum and get the equation:
       * Math.pow(sum, 2) - 24 * (a + b) + 2a*b = 0;
       * we consider b >= a;
       */
      double sum = sc.nextDouble();
      double ablimits = Math.floor(sum / 3 * 2); // a + b <= ablimits
      double alimits = Math.floor(ablimits / 2); // a <= alimits
      //System.out.println("another round");
      //System.out.print(alimits + " " + blimits);
      A: for (double a = 1; a <= alimits; a++) {
        B: for (double b = a; b <= sum - a; b++) {
          double result = Math.pow((sum-a-b),2)-a*a-b*b;
          //System.out.print("when a is " + a + " " + "when b is " + b + ":" + result + ";");
          if (Math.pow(sum, 2) - 2 * sum * (a + b) + 2 * a * b == 0) {
            double answer = a*a + b*b;
            int output = (int)answer;
            System.out.print(output + " ");
            break A;
          }
        }
      }

    }
  }
}

When I input 1 12 , it gives 25(because a,b,c=3,4,5; c^2 = 25 ), but it can't handle big inputs like 14808286 because my algorithm is not efficient enough. What is the efficient way to do this? Plz!

Let me preface this by saying I don't have intimate knowledge of Pythagorean triples or the math behind them. I just thought this was an interesting problem, so I gave it a stab.

I believe the key to this problem is knowing what you're looking for as you scan through possible values of a. Given

a + b + c = sum

and

a^2 + b^2 = c^2

you'll find that

b = (sum / 2) * (1 - (a / (sum - a)))
  = (sum / 2) - ((a * sum) / (2 * (sum - a)))

You know that b must be a whole number. An interesting property of Pythagorean triples is that their sums are always even. That means that

(sum / 2) % 1 = 0

So all we really need to check to make sure b is valid (ie a whole number) is that

((a * sum) / (2 * (sum - a))) % 1 = 0

or, put more simply,

(a * sum) % (sum - a) = 0

Some other key points that simplify this problem, at least as you've stated it:

  • Once you have a, b can be computed using the third equation in this answer.
  • Once you have a and b, c follows easily from either of the Pythagorean triple equations.
  • You only need to print c^2 as your output. Once this is done you can break.

The code ends up being pretty simple:

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    // Get the sum from System.in.
    int sum = sc.nextInt();

    // If the given sum is odd, return immediately.
    // No Pythagorean triple will have an odd sum.
    if ((sum ^ 1) == 1) {
        return;
    }

    // Try all values of a within the expected bounds.
    int aBound = sum / 2;
    for (int a = 1; a < aBound; a++) {
        // Check whether b would be a whole number with this value of a.
        if ((a * sum) % (a - sum) == 0) {
            int b = (sum * (2 * a - sum)) / (2 * a - 2 * sum);
            int c = sum - a - b;
            System.out.println((int)Math.pow(c, 2));
            break;
        }
    }
}

It's worth noting that because I lack deep mathematical understanding of Pythagorean triples, there's very likely some further optimization that can be done in deciding which values of a actually need to be checked. I imagine there's some mathematical criteria for that.

I hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM