diff --git a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-128-hexagonal-tile-differences.md b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-128-hexagonal-tile-differences.md index 80309b4cff3..5aaf48ab2f5 100644 --- a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-128-hexagonal-tile-differences.md +++ b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-128-hexagonal-tile-differences.md @@ -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++; } diff --git a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-47-distinct-primes-factors.md b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-47-distinct-primes-factors.md index 978b7affd9b..3b79403a4ea 100644 --- a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-47-distinct-primes-factors.md +++ b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-47-distinct-primes-factors.md @@ -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; } ``` diff --git a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-50-consecutive-prime-sum.md b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-50-consecutive-prime-sum.md index 861a3e99a8e..7cd5bc67b14 100644 --- a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-50-consecutive-prime-sum.md +++ b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-50-consecutive-prime-sum.md @@ -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; diff --git a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-51-prime-digit-replacements.md b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-51-prime-digit-replacements.md index 26aed0ce89a..cdbfc3e568b 100644 --- a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-51-prime-digit-replacements.md +++ b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-51-prime-digit-replacements.md @@ -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; } }