| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | --- | 
					
						
							|  |  |  | id: 5900f39e1000cf542c50feb1 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | title: 'Problema 50: Soma dos números primos consecutivos' | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | challengeType: 5 | 
					
						
							|  |  |  | forumTopicId: 302161 | 
					
						
							|  |  |  | dashedName: problem-50-consecutive-prime-sum | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # --description--
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | O número primo 41 pode ser escrito como a soma de seis números primos consecutivos: | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | <div style='text-align: center;'>41 = 2 + 3 + 5 + 7 + 11 + 13</div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | Esta é a soma mais longa de números primos consecutivos abaixo de 100 que resultam em um número primo. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | A soma mais longa de números primos consecutivos abaixo de 1000 contém 21 termos e resulta em 953. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | Qual número primo, abaixo de um milhão, é o resultado da soma da maior sequência de números primos? | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # --hints--
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | `consecutivePrimeSum(1000)` deve retornar um número. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | assert(typeof consecutivePrimeSum(1000) === 'number'); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | `consecutivePrimeSum(1000)` deve retornar 953. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | assert.strictEqual(consecutivePrimeSum(1000), 953); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 09:12:11 -07:00
										 |  |  | `consecutivePrimeSum(1000000)` deve retornar 997651. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | assert.strictEqual(consecutivePrimeSum(1000000), 997651); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # --seed--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## --seed-contents--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function consecutivePrimeSum(limit) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | consecutivePrimeSum(1000000); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # --solutions--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2021-12-23 23:35:44 +05:30
										 |  |  | // 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; | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-23 23:35:44 +05:30
										 |  |  |   for (let i = sqrtUpper + 1; i < upper; i++) { | 
					
						
							|  |  |  |     if (PRIME_SIEVE[i]) | 
					
						
							|  |  |  |       PRIMES.push(2 * i + 3); | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-23 23:35:44 +05:30
										 |  |  | })(NUM_PRIMES); | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-23 23:35:44 +05:30
										 |  |  | 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]; | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-23 23:35:44 +05:30
										 |  |  |     // -- Increment outer loop | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  |     j = i + (bestJ - bestI); | 
					
						
							|  |  |  |     sumOfCurrRange -= PRIMES[i - 1]; | 
					
						
							|  |  |  |     sumOfCurrRange += PRIMES[j]; | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-23 23:35:44 +05:30
										 |  |  |   // Return | 
					
						
							|  |  |  |   return bestPrime; | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | } | 
					
						
							|  |  |  | ``` |