mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-13 16:04:36 -04:00
129 lines
3.4 KiB
Markdown
129 lines
3.4 KiB
Markdown
---
|
|
id: 5900f39f1000cf542c50feb2
|
|
title: 'Problem 51: Prime digit replacements'
|
|
challengeType: 1
|
|
forumTopicId: 302162
|
|
dashedName: problem-51-prime-digit-replacements
|
|
---
|
|
|
|
# --description--
|
|
|
|
By replacing the 1st digit of the 2-digit number \*3, it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.
|
|
|
|
By replacing the 3rd and 4th digits of 56\*\*3 with the same digit, this 5-digit number is the first example having seven primes among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993. Consequently 56003, being the first member of this family, is the smallest prime with this property.
|
|
|
|
Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an `n` prime value family.
|
|
|
|
# --hints--
|
|
|
|
`primeDigitReplacements(6)` should return a number.
|
|
|
|
```js
|
|
assert(typeof primeDigitReplacements(6) === 'number');
|
|
```
|
|
|
|
`primeDigitReplacements(6)` should return `13`.
|
|
|
|
```js
|
|
assert.strictEqual(primeDigitReplacements(6), 13);
|
|
```
|
|
|
|
`primeDigitReplacements(7)` should return `56003`.
|
|
|
|
```js
|
|
assert.strictEqual(primeDigitReplacements(7), 56003);
|
|
```
|
|
|
|
`primeDigitReplacements(8)` should return `121313`.
|
|
|
|
```js
|
|
assert.strictEqual(primeDigitReplacements(8), 121313);
|
|
```
|
|
|
|
# --seed--
|
|
|
|
## --seed-contents--
|
|
|
|
```js
|
|
function primeDigitReplacements(n) {
|
|
|
|
return true;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
})(NUM_PRIMES);
|
|
|
|
function isPrime(num) {
|
|
if (num === 2) return true;
|
|
else if (num % 2 === 0) return false
|
|
else return PRIME_SEIVE[(num - 3) / 2];
|
|
}
|
|
|
|
function primeDigitReplacements(n) {
|
|
function isNFamily(number, n) {
|
|
const prime = number.toString();
|
|
const lastDigit = prime[prime.length - 1];
|
|
return doesReplacingMakeFamily(prime, '0', n) ||
|
|
doesReplacingMakeFamily(prime, '2', n) ||
|
|
(lastDigit !== '1' && doesReplacingMakeFamily(prime, '1', n));
|
|
}
|
|
|
|
function doesReplacingMakeFamily(prime, digitToReplace, family) {
|
|
let miss = 0;
|
|
const base = parseInt(
|
|
prime
|
|
.split('')
|
|
.map(digit => digit == digitToReplace ? '0' : digit)
|
|
.join('')
|
|
);
|
|
const replacements = parseInt(
|
|
prime
|
|
.split('')
|
|
.map(digit => digit === digitToReplace ? '1' : '0')
|
|
.join('')
|
|
);
|
|
const start = prime[0] === digitToReplace ? 1 : 0;
|
|
for (let i = start; i < 10; i++) {
|
|
const nextNumber = base + i * replacements;
|
|
if (!isPartOfFamily(nextNumber, prime)) miss++;
|
|
if (10 - start - miss < family) break;
|
|
}
|
|
return 10 - start - miss === family;
|
|
}
|
|
|
|
function isPartOfFamily(number, prime) {
|
|
return (
|
|
isPrime(number) && number.toString().length === prime.length
|
|
);
|
|
}
|
|
|
|
for (let number = 1; number < 125000; number++) {
|
|
if (isPrime(number) && isNFamily(number, n)) {
|
|
return number;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
```
|