2.9 KiB
2.9 KiB
id | title | challengeType | forumTopicId | dashedName |
---|---|---|---|---|
5900f39e1000cf542c50feb1 | Problema 50: somma di primi consecutivi | 5 | 302161 | problem-50-consecutive-prime-sum |
--description--
Il primo 41, può essere scritto come la somma di sei primi consecutivi:
41 = 2 + 3 + 5 + 7 + 11 + 13
Questa è la somma più lunga di primi consecutivi che dà come somma un primo sotto il cento.
La somma più lunga di primi consecutivi sotto il mille che dà come somma un primo, contiene 21 termini, ed è pari a 953.
Quale primo, al di sotto di un milione, può essere scritto come la somma del maggior numero di numeri primi consecutivi?
--hints--
consecutivePrimeSum(1000)
dovrebbe restituire un numero.
assert(typeof consecutivePrimeSum(1000) === 'number');
consecutivePrimeSum(1000)
dovrebbe restituire 953.
assert.strictEqual(consecutivePrimeSum(1000), 953);
consecutivePrimeSum(1000000)
dovrebbe restituire 997651.
assert.strictEqual(consecutivePrimeSum(1000000), 997651);
--seed--
--seed-contents--
function consecutivePrimeSum(limit) {
return true;
}
consecutivePrimeSum(1000000);
--solutions--
// Initalize prime number list with sieve
const NUM_PRIMES = 1000000;
const PRIMES = [2];
const PRIME_SIEVE = Array(Math.floor((NUM_PRIMES-1)/2)).fill(true);
(function initPrimes(num) {
const upper = Math.floor((num - 1) / 2);
const sqrtUpper = Math.floor((Math.sqrt(num) - 1) / 2);
for (let i = 0; i <= sqrtUpper; i++) {
if (PRIME_SIEVE[i]) {
// Mark value in PRIMES array
const prime = 2 * i + 3;
PRIMES.push(prime);
// Mark all multiples of this number as false (not prime)
const primeSqaredIndex = 2 * i ** 2 + 6 * i + 3;
for (let j = primeSqaredIndex; j < upper; j += prime)
PRIME_SIEVE[j] = false;
}
}
for (let i = sqrtUpper + 1; i < upper; i++) {
if (PRIME_SIEVE[i])
PRIMES.push(2 * i + 3);
}
})(NUM_PRIMES);
function isPrime(num) {
if (num === 2)
return true;
else if (num % 2 === 0)
return false
else
return PRIME_SIEVE[(num - 3) / 2];
}
function consecutivePrimeSum(limit) {
// Initalize for longest sum < 100
let bestPrime = 41;
let bestI = 0;
let bestJ = 5;
// Find longest sum < limit
let sumOfCurrRange = 41;
let i = 0, j = 5;
// -- Loop while current some starting at i is < limit
while (sumOfCurrRange < limit) {
let currSum = sumOfCurrRange;
// -- Loop while pushing j towards end of PRIMES list
// keeping sum under limit
while (currSum < limit) {
if (isPrime(currSum)) {
bestPrime = sumOfCurrRange = currSum;
bestI = i;
bestJ = j;
}
// -- Increment inner loop
j++;
currSum += PRIMES[j];
}
// -- Increment outer loop
i++;
j = i + (bestJ - bestI);
sumOfCurrRange -= PRIMES[i - 1];
sumOfCurrRange += PRIMES[j];
}
// Return
return bestPrime;
}