Anonymous user
Pythagorean triples/Java/Brute force primitives: Difference between revisions
Pythagorean triples/Java/Brute force primitives (view source)
Revision as of 20:45, 20 December 2011
, 12 years agoSomewhere in there I got rid of the need for 12 as a BigInteger, reformat
m (It turns out that the GCD check can speed it up a little bit) |
m (Somewhere in there I got rid of the need for 12 as a BigInteger, reformat) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 1:
{{works with|Java|1.5+}}
This version brute forces primitive triple candidates and then scales them to find the rest (under the perimeter limit of course). Since it only finds the primitives mathematically it can optimize its candidates based on some of the properties [[wp:Pythagorean_triple#Elementary_properties_of_primitive_Pythagorean_triples|here]] -- namely that a and b have opposite evenness, only one of a and b is divisible by 3, only one of a and b is divisible by 4, c is always odd, and that a<sup>2</sup> + b<sup>2</sup> must be a perfect square (which [[wp:Square_number#Properties|don't ever end in 2, 3, 7, or 8]]). After using those rules to eliminate candidates for a,b pairs, it checks that a and b are coprime. Since many a,b pair candidates have already been eliminated, this check actually speeds things up a little bit by letting the program skip some c loops. For a perimeter limit of 1000, it is about 5 times faster than [[Pythagorean triples#Java|the other brute force version]]. For a perimeter limit of 10000, it is about 17 times faster. It also
It defines a <code>Triple</code> class which is comparable so it can be placed in a <code>TreeSet</code> for easy sorting and to remove duplicates (the GCD check should remove duplicates, but it's nice to make sure). It also can scale itself by an integer factor.
Line 8:
import java.util.Set;
import java.util.TreeSet;
import static java.math.BigInteger.*;
public class PythTrip{
B12 = BigInteger.valueOf(12),▼
private static BigInteger
B127 = BigInteger.valueOf(127),▼
BigInteger a, b, c, peri;
▲ //change this to whatever perimeter limit you want;the RAM's the limit
public Triple(BigInteger a, BigInteger b, BigInteger c, boolean prim){
▲ public static class Triple implements Comparable<Triple>{
peri = a.add(b).add(c);▼
public Triple scale(long
public Triple scale(long k){▼
▲ }
Triple trip
return a.equals(trip.a) &&
}▼
▲ }
public int compareTo(Triple
▲ @Override
long primCount = 0;
long start = System.currentTimeMillis();
BigInteger peri2 = LIMIT.divide(TWO), peri3 = LIMIT.divide(B3);
peri3 = LIMIT.divide(B3);▼
for(BigInteger a = B3; a.compareTo(peri3) < 0; a = a.add(ONE)){
Line 83 ⟶ 84:
//b is the opposite evenness of a so increment by 2
for(BigInteger b = a.add(ONE); b.compareTo(peri2) < 0; b = b
|| amod4 == b.mod(B4).equals(ZERO))
//if a^2+b^2 isn't a perfect square, don't even test for c's
BigInteger aabb = aa.add(b.multiply(b));
if((aabb.and(B7).intValue() != 1)
&& (aabb.and(B31).intValue() != 4)
&& (aabb.and(B127).intValue() != 16)
&& (aabb.and(B191).intValue() != 0))
if(!a.gcd(b).equals(ONE))
BigInteger ab = a.add(b);
// otherwise
for(BigInteger c = b.add(b.testBit(0)
break;▼
int compare = aabb.compareTo(c.multiply(c));
// if a^2 + b^2 != c^2
if(compare < 0){
break;
}else if
Triple prim = new Triple(a, b, c, true);
if(trips.add(prim)){
primCount++;
addAllScales(prim);
}
}
Line 118 ⟶ 123:
}
}
for(Triple trip : trips){
System.out.println(trip);
}
System.out.println("Runtime: " + (System.currentTimeMillis() - start));
System.out.println("Up to a perimeter of " + LIMIT + ", there are "
+ trips.size() + " triples, of which " + primCount
}
}</lang>
Output:
<pre>3, 4, 5 primitive
5, 12, 13 primitive
6, 8, 10
7, 24, 25 primitive
8, 15, 17 primitive
9, 12, 15
9, 40, 41 primitive
10, 24, 26
12, 16, 20
12, 35, 37 primitive
15, 20, 25
15, 36, 39
16, 30, 34
18, 24, 30
20, 21, 29 primitive
21, 28, 35
24, 32, 40
|