1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FastLacroix {
interface LacroixAlgorithm {
void execute(long start, long end);
}
static class Algo3 implements LacroixAlgorithm {
@Override
public void execute(long start, long end) {
final long[] powers10 = powers10Long();
final int nbrDigitsMax = (int) Math.log10(end) + 1;
end = end++;
// Calcul de la première valeur
long number = start;
final long nbrSquared = number * number;
int nbrDigits = (int) Math.log10(number) + 1;
long divisor = powers10[nbrDigits - 1];
long b1 = nbrSquared / divisor;
long b0 = nbrSquared % divisor;
long result = b1 - b0;
if (result == number) {
System.out.println(number);
}
number++;
for (int i = nbrDigits; i <= nbrDigitsMax; i++, number++) {
final long nbrMaxE = powers10[i];
divisor = powers10[i - 1];
final long endBoucle = Math.min(nbrMaxE, end);
while (number < endBoucle) {
final long newCalc = 2 * number - 1;
b0 += newCalc % divisor;
b1 += newCalc / divisor;
if (b0 > divisor) {
b0 = b0 - divisor;
b1++;
}
result = b1 - b0;
if (result == number) {
System.out.println(number);
}
number++;
}
b1 = number;
b0 = 0;
result = number;
}
}
private static long[] powers10Long() {
long[] powers10 = new long[19];
long l = 1;
for (int i = 0; i < 19; i++) {
powers10[i] = l;
l *= 10;
}
return powers10;
}
}
private static final int PROCESSOR_COUNT = Runtime.getRuntime().availableProcessors();
private static ExecutorService EXECUTOR = Executors.newFixedThreadPool(PROCESSOR_COUNT);
private static final long TASK_SIZE = 1l << 28;
private static long current = 10;
/**
* @param args
*/
public static void main(String[] args) {
for(int i = 0; i < PROCESSOR_COUNT; i++) {
EXECUTOR.execute(next());
}
}
private static synchronized Runnable next() {
final long current = FastLacroix.current;
FastLacroix.current += TASK_SIZE;
Runnable runnable = new Runnable() {
@Override public void run() {
LacroixAlgorithm algo = new Algo3();
//System.out.println("nouvelle tâche");
algo.execute(current, current + TASK_SIZE - 1);
EXECUTOR.execute(next());
}
};
return runnable;
}
} |