Poniżej takie rozwiązanie brute force i z brzydkim ręcznym rozpisaniem pętli, ale za to z prymitywną wielowątkowością.
Uwaga na przekręcenie się longów, to działa z niewielkim zapasem.
Dosyć oczywistą obserwacją jest że dla niewielkich liczb pewnie nie ma żadnych reguł, ale jeżeli masz już co najmniej jedną dużą liczbę, to jedna z liczb musi być bardzo mała.
Można poszlifować program w tym kierunku, aby dla pewnego zakresu przetwarzał wszystkie liczby, a od pewnego momentu ograniczał kolejne liczby (np. dla >500 i >1 trzecia liczba musi być bliska zera).
Wydaje mi się, że te punkty w przestrzeni N-wymiarowej są bardzo rzadkie i brute-force tutaj ma krótkie nóżki, można spróbować napisać to w kierunku np. algorytmu genetycznego lub podobnych metod przeszukiwania ogromnych przestrzeni poszukiwań.
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;
public class SumProduct {
private static final Set<List<Long>> results = new HashSet<>();
public static void main(String[] args) {
int divisor = Runtime.getRuntime().availableProcessors();
int length = divisor * 16_000;
IntStream.rangeClosed(0, -1 + divisor).asLongStream().parallel().forEach(threadNumber -> {
long rangeS = (length / divisor) * threadNumber;
long rangeE = (length / divisor) * (threadNumber + 1);
long x1, x2, x3;
log("wątek[" + threadNumber + "]: rangeS " + rangeS + ", rangeE " + rangeE);
for (x1 = rangeS; x1 < rangeE; x1++) {
if (x1 % 100 == 0) {
// log("wątek[" + threadNumber + "]: progress " + (1.0 * (x1 - rangeS) / (rangeE - rangeS)));
}
for (x2 = 0; x2 < 2400; x2++) {
for (x3 = 0; x3 < 150; x3++) {
if ((x1 + x2 + x3) * (100 * 100) == x1 * x2 * x3) {
List<Long> res = Arrays.asList(x1, x2, x3);
Collections.sort(res);
if (!results.contains(res)) {
results.add(res);
log(Arrays.asList(toStr(x1), toStr(x2), toStr(x3)));
}
}
}
}
}
});
log("total results==" + results.size());
}
private static void log(Object o) {
System.out.println(o);
}
private static String toStr(long x1) {
String s = "" + x1;
if (s.length() == 1) {
s = "0.0" + x1;
} else if (s.length() == 2) {
s = "0." + x1;
} else {
s = s.substring(0, s.length() - 2) + "." + s.substring(s.length() - 2);
}
return s;
}
}