I would like to find the highest value m = a*b that satisfies some condition C(m), where
1 <= a <= b <= 1,000,000.
In order to do
Note: this is a test of the function C(m) where m <= some target. It will not work for OP's general situation, but is a side case.
First find the highest number that satisfies C, and then find the pair that matches that high number. Finding the initial target number takes almost no time since its a binary search from 1 to 1E12. Finding the pair that matches is a bit harder, but is still not as bad as factoring.
Code:
public class TargetPractice {
private static final long MAX = 1000000L;
private long target;
public static void main(String[] args) {
Random r = new Random();
for (int i = 0; i < 5; i++) {
TargetPractice tp = new TargetPractice(r.nextInt((int) MAX), r.nextInt((int) MAX));
System.out.println("Trying to find " + tp.target);
System.gc();
long start = System.currentTimeMillis();
long foundTarget = tp.findTarget();
long end = System.currentTimeMillis();
System.out.println("Found " + foundTarget);
System.out.println("Elapsed time " + (end - start) + "\n");
}
}
public TargetPractice(long a, long b) {
target = a * b + 1;
}
private long binSearch() {
double delta = MAX * MAX / 2;
double target = delta;
while (delta != 0) {
if (hit((long) target)) {
target = target + delta / 2;
} else {
target = target - delta / 2;
}
delta = delta / 2;
}
long longTarget = (long) target;
for (int i = 10; i >= -10; i--) {
if (hit(longTarget + i)) {
return longTarget + i;
}
}
return -1;
}
private long findTarget() {
long target = binSearch();
long b = MAX;
while (target / b * b != target || target / b > MAX) {
b--;
if (b == 0 || target / b > MAX) {
b = MAX;
target--;
}
}
System.out.println("Found the pair " + (target/b) + ", " + b);
return target;
}
public boolean hit(long n) {
return n <= target;
}
}
It prints:
Trying to find 210990777760
Found the pair 255976, 824260
Found 210990777760
Elapsed time 5
Trying to find 414698196925
Found the pair 428076, 968749
Found 414698196924
Elapsed time 27Trying to find 75280777586
Found the pair 78673, 956882
Found 75280777586
Elapsed time 1Trying to find 75327435877
Found the pair 82236, 915991
Found 75327435876
Elapsed time 19Trying to find 187413015763
Found the pair 243306, 770277
Found 187413015762
Elapsed time 23