freeCodeCamp/curriculum/challenges/italian/10-coding-interview-prep/project-euler/problem-50-consecutive-prim...

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;
}