mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-29 08:00:43 -04:00
fix(curriculum): Faster Euler tests for prime seive problems (#48158)
This commit is contained in:
committed by
GitHub
parent
326e00fab8
commit
33a95e4e10
@@ -56,46 +56,57 @@ hexagonalTile(10);
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const NUM_PRIMES = 840000;
|
||||
const PRIME_SEIVE = 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_SEIVE[i]) {
|
||||
// Mark value in PRIMES array
|
||||
const prime = 2 * i + 3;
|
||||
// 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_SEIVE[j] = false;
|
||||
class PrimeSeive {
|
||||
constructor(num) {
|
||||
const seive = Array(Math.floor((num - 1) / 2)).fill(true);
|
||||
const upper = Math.floor((num - 1) / 2);
|
||||
const sqrtUpper = Math.floor((Math.sqrt(num) - 1) / 2);
|
||||
|
||||
for (let i = 0; i <= sqrtUpper; i++) {
|
||||
if (seive[i]) {
|
||||
// Mark value in seive array
|
||||
const prime = 2 * i + 3;
|
||||
// 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) {
|
||||
seive[j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})(NUM_PRIMES);
|
||||
|
||||
function isPrime(num) {
|
||||
if (num === 2) return true;
|
||||
else if (num % 2 === 0) return false
|
||||
else return PRIME_SEIVE[(num - 3) / 2];
|
||||
}
|
||||
this._seive = seive;
|
||||
}
|
||||
|
||||
isPrime(num) {
|
||||
return num === 2
|
||||
? true
|
||||
: num % 2 === 0
|
||||
? false
|
||||
: this.isOddPrime(num);
|
||||
}
|
||||
|
||||
isOddPrime(num) {
|
||||
return this._seive[(num - 3) / 2];
|
||||
}
|
||||
};
|
||||
|
||||
function hexagonalTile(tileIndex) {
|
||||
const primeSeive = new PrimeSeive(tileIndex * 420);
|
||||
let count = 1;
|
||||
let n = 1;
|
||||
let number = 0;
|
||||
|
||||
while (count < tileIndex) {
|
||||
if (isPrime(6*n - 1) &&
|
||||
isPrime(6*n + 1) &&
|
||||
isPrime(12*n + 5)) {
|
||||
if (primeSeive.isPrime(6*n - 1) &&
|
||||
primeSeive.isPrime(6*n + 1) &&
|
||||
primeSeive.isPrime(12*n + 5)) {
|
||||
number = 3*n*n - 3*n + 2;
|
||||
count++;
|
||||
if (count >= tileIndex) break;
|
||||
}
|
||||
if (isPrime(6*n + 5) &&
|
||||
isPrime(6*n - 1) &&
|
||||
isPrime(12*n - 7) && n != 1) {
|
||||
if (primeSeive.isPrime(6*n + 5) &&
|
||||
primeSeive.isPrime(6*n - 1) &&
|
||||
primeSeive.isPrime(12*n - 7) && n != 1) {
|
||||
number = 3*n*n + 3*n + 1;
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -67,25 +67,28 @@ distinctPrimeFactors(4, 4);
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
// Initalize factor count with seive
|
||||
const NUMFACTORS = Array(135000).fill(0);
|
||||
(function initFactors(num) {
|
||||
for (let i = 2; i < num; i++)
|
||||
if (NUMFACTORS[i] === 0)
|
||||
for (let j = i; j < num; j += i)
|
||||
NUMFACTORS[j]++;
|
||||
})(135000);
|
||||
|
||||
function distinctPrimeFactors(targetNumPrimes, targetConsecutive) {
|
||||
const primeLimit = targetNumPrimes * targetConsecutive * 10000;
|
||||
const numFactors = Array(primeLimit).fill(0);
|
||||
|
||||
let numConsecutive = 0;
|
||||
let currNumber = 10;
|
||||
while (numConsecutive < targetConsecutive) {
|
||||
if (NUMFACTORS[currNumber] === targetNumPrimes)
|
||||
for (let i = 2; i < primeLimit; i++) {
|
||||
if (numFactors[i] === targetNumPrimes) {
|
||||
// Current number is composite with target num factors
|
||||
numConsecutive++;
|
||||
else
|
||||
if (numConsecutive === targetConsecutive) {
|
||||
return i - numConsecutive + 1;
|
||||
}
|
||||
} else {
|
||||
// Current number is not matching composite
|
||||
numConsecutive = 0;
|
||||
currNumber++;
|
||||
if (numFactors[i] === 0) {
|
||||
// Current number is prime
|
||||
for (let j = i; j < primeLimit; j += i) {
|
||||
numFactors[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return currNumber - targetConsecutive;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -54,40 +54,56 @@ consecutivePrimeSum(1000000);
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
// 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);
|
||||
class PrimeSeive {
|
||||
constructor(num) {
|
||||
const seive = Array(Math.floor((num - 1) / 2)).fill(true);
|
||||
const primes = [2];
|
||||
const upper = Math.floor((num - 1) / 2);
|
||||
const sqrtUpper = Math.floor((Math.sqrt(num) - 1) / 2);
|
||||
|
||||
function isPrime(num) {
|
||||
if (num === 2)
|
||||
return true;
|
||||
else if (num % 2 === 0)
|
||||
return false
|
||||
else
|
||||
return PRIME_SIEVE[(num - 3) / 2];
|
||||
}
|
||||
for (let i = 0; i <= sqrtUpper; i++) {
|
||||
if (seive[i]) {
|
||||
// Mark value in seive 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) {
|
||||
seive[j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = sqrtUpper + 1; i < upper; i++) {
|
||||
if (seive[i]) {
|
||||
primes.push(2 * i + 3);
|
||||
}
|
||||
}
|
||||
|
||||
this._seive = seive;
|
||||
this._primes = primes;
|
||||
}
|
||||
|
||||
isPrime(num) {
|
||||
return num === 2
|
||||
? true
|
||||
: num % 2 === 0
|
||||
? false
|
||||
: this.isOddPrime(num);
|
||||
}
|
||||
|
||||
isOddPrime(num) {
|
||||
return this._seive[(num - 3) / 2];
|
||||
}
|
||||
|
||||
get primes() {
|
||||
return this._primes;
|
||||
}
|
||||
};
|
||||
|
||||
function consecutivePrimeSum(limit) {
|
||||
// Initalize seive
|
||||
const primeSeive = new PrimeSeive(limit);
|
||||
|
||||
// Initalize for longest sum < 100
|
||||
let bestPrime = 41;
|
||||
let bestI = 0;
|
||||
@@ -102,20 +118,20 @@ function consecutivePrimeSum(limit) {
|
||||
// -- Loop while pushing j towards end of PRIMES list
|
||||
// keeping sum under limit
|
||||
while (currSum < limit) {
|
||||
if (isPrime(currSum)) {
|
||||
if (primeSeive.isPrime(currSum)) {
|
||||
bestPrime = sumOfCurrRange = currSum;
|
||||
bestI = i;
|
||||
bestJ = j;
|
||||
}
|
||||
// -- Increment inner loop
|
||||
j++;
|
||||
currSum += PRIMES[j];
|
||||
currSum += primeSeive.primes[j];
|
||||
}
|
||||
// -- Increment outer loop
|
||||
i++;
|
||||
j = i + (bestJ - bestI);
|
||||
sumOfCurrRange -= PRIMES[i - 1];
|
||||
sumOfCurrRange += PRIMES[j];
|
||||
sumOfCurrRange -= primeSeive.primes[i - 1];
|
||||
sumOfCurrRange += primeSeive.primes[j];
|
||||
}
|
||||
// Return
|
||||
return bestPrime;
|
||||
|
||||
@@ -56,31 +56,43 @@ primeDigitReplacements(6);
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const NUM_PRIMES = 1000000;
|
||||
const PRIME_SEIVE = 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_SEIVE[i]) {
|
||||
// Mark value in PRIMES array
|
||||
const prime = 2 * i + 3;
|
||||
// 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_SEIVE[j] = false;
|
||||
class PrimeSeive {
|
||||
constructor(num) {
|
||||
const seive = Array(Math.floor((num - 1) / 2)).fill(true);
|
||||
const upper = Math.floor((num - 1) / 2);
|
||||
const sqrtUpper = Math.floor((Math.sqrt(num) - 1) / 2);
|
||||
|
||||
for (let i = 0; i <= sqrtUpper; i++) {
|
||||
if (seive[i]) {
|
||||
// Mark value in seive array
|
||||
const prime = 2 * i + 3;
|
||||
// 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) {
|
||||
seive[j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})(NUM_PRIMES);
|
||||
|
||||
function isPrime(num) {
|
||||
if (num === 2) return true;
|
||||
else if (num % 2 === 0) return false
|
||||
else return PRIME_SEIVE[(num - 3) / 2];
|
||||
}
|
||||
this._seive = seive;
|
||||
}
|
||||
|
||||
isPrime(num) {
|
||||
return num === 2
|
||||
? true
|
||||
: num % 2 === 0
|
||||
? false
|
||||
: this.isOddPrime(num);
|
||||
}
|
||||
|
||||
isOddPrime(num) {
|
||||
return this._seive[(num - 3) / 2];
|
||||
}
|
||||
};
|
||||
|
||||
function primeDigitReplacements(n) {
|
||||
const primeSeive = new PrimeSeive(n * n * n * 2000);
|
||||
|
||||
function isNFamily(number, n) {
|
||||
const prime = number.toString();
|
||||
const lastDigit = prime[prime.length - 1];
|
||||
@@ -114,12 +126,12 @@ function primeDigitReplacements(n) {
|
||||
|
||||
function isPartOfFamily(number, prime) {
|
||||
return (
|
||||
isPrime(number) && number.toString().length === prime.length
|
||||
primeSeive.isPrime(number) && number.toString().length === prime.length
|
||||
);
|
||||
}
|
||||
|
||||
for (let number = 1; number < 125000; number++) {
|
||||
if (isPrime(number) && isNFamily(number, n)) {
|
||||
if (primeSeive.isPrime(number) && isNFamily(number, n)) {
|
||||
return number;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user