जावा 8: 1.8e8 2.4e8
इस प्रविष्टि की तुलना पहले से ही किए गए कई अन्य लोगों से नहीं है, लेकिन मैं अपना जवाब पोस्ट करना चाहता था क्योंकि मुझे इस पर काम करने में मज़ा आया।
मेरे दृष्टिकोण के मुख्य अनुकूलन निम्नानुसार हैं:
- हर सम संख्या में 2 का सबसे छोटा कारक होता है, इसलिए हर विषम संख्या के संसाधित होने के बाद इन्हें मुफ्त में जोड़ा जा सकता है। मूल रूप से, यदि आपने काम किया है कि गणना
T(N)
कब N % 2 == 1
, आप जानते हैं T(N + 1) == T(N) + 2
। यह मुझे तीन पर अपनी गिनती शुरू करने और दो बार पुनरावृत्ति द्वारा वृद्धि करने की अनुमति देता है।
- मैं एक प्रकार के विपरीत एक सरणी में अपनी प्रमुख संख्याओं को संग्रहीत करता हूं
Collection
। इससे दोगुना से अधिक N
मैं पहुंच सकता हूं।
- मैं एराटोस्थनीज की छलनी का विरोध करने के लिए एक संख्या को कारक के लिए अभाज्य संख्याओं का उपयोग करता हूं। इसका मतलब यह है कि मेरी मेमोरी स्टोरेज लगभग पूरी तरह से मेरे प्राइम सरणी में प्रतिबंधित है।
- मैं उस संख्या के वर्गमूल को संग्रहीत करता हूं जिसके लिए मैं सबसे छोटा कारक खोजने की कोशिश कर रहा हूं। मैंने हर बार प्राइम फैक्टर को स्क्वेर करने के लिए @ user1354678 के दृष्टिकोण की कोशिश की, लेकिन इसने मुझे मेरे स्कोर से लगभग 1e7 की लागत दी।
इसके बारे में बस इतना ही है। मेरा कोड 3 से twos द्वारा पुनरावृत्ति करता है जब तक कि यह पता नहीं लगाता है कि यह हिट हो गई है या समय सीमा पार कर गई है, जिस बिंदु पर यह उत्तर को बाहर निकालता है।
package sum_of_smallest_factors;
public final class SumOfSmallestFactors {
private static class Result {
private final int number;
int getNumber() {
return number;
}
private final long sum;
long getSum() {
return sum;
}
Result(int number, long sum) {
this.number = number;
this.sum = sum;
}
}
private static final long TIME_LIMIT = 60_000_000_000L; // 60 seconds x 1e9 nanoseconds / second
public static void main(String[] args) {
SumOfSmallestFactors main = new SumOfSmallestFactors();
Result result = main.run();
int number = result.getNumber();
long sum = result.getSum();
System.out.format("T(%,d) = %,d\n", number, sum);
}
private int[] primes = new int[16_777_216];
private int primeCount = 0;
private long startTime;
private SumOfSmallestFactors() {}
private Result run() {
startClock();
int number;
long sumOfSmallestFactors = 2;
for (number = 3; mayContinue(); number += 2) {
int smallestFactor = getSmallestFactor(number);
if (smallestFactor == number) {
addPrime(number);
}
sumOfSmallestFactors += smallestFactor + 2;
}
--number;
Result result = new Result(number, sumOfSmallestFactors);
return result;
}
private void startClock() {
startTime = System.nanoTime();
}
private boolean mayContinue() {
long currentTime = System.nanoTime();
long elapsedTime = currentTime - startTime;
boolean result = (elapsedTime < TIME_LIMIT);
return result;
}
private int getSmallestFactor(int number) {
int smallestFactor = number;
int squareRoot = (int) Math.ceil(Math.sqrt(number));
int index;
int prime = 3;
for (index = 0; index < primeCount; ++index) {
prime = primes[index];
if (prime > squareRoot) {
break;
}
int remainder = number % prime;
if (remainder == 0) {
smallestFactor = prime;
break;
}
}
return smallestFactor;
}
private void addPrime(int prime) {
primes[primeCount] = prime;
++primeCount;
}
}
जावा 8 के नवीनतम संस्करण के साथ एक अलग प्रणाली (विंडोज 8.1, इंटेल कोर i7 @ 2.5 गीगाहर्ट्ज, 8 जीबी रैम) पर चलने से बिना किसी कोड परिवर्तन के बेहतर परिणाम सामने आए हैं।
T(240,308,208) = 1,537,216,753,010,879