Files
freeCodeCamp/curriculum/challenges/japanese/10-coding-interview-prep/project-euler/problem-58-spiral-primes.md
2022-01-20 20:30:18 +01:00

2.8 KiB

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5900f3a61000cf542c50feb9 問題 58: らせん素数 5 302169 problem-58-spiral-primes

--description--

次のように 1 から始めて反時計回りにらせん状に数字を置いていくと、辺の長さが 7 の正方形のらせんができます。

37 36 35 34 33 32 31
38 17 16 15 14 13 30
39 18  5  4  3 12 29
40 19  6  1  2 11 28
41 20  7  8  9 10 27
42 21 22 23 24 25 26
43 44 45 46 47 48 49

興味深いことに、右下の対角線上に奇数の平方数が現れます。しかしもっと興味深いのは、両方の対角線上にある 13 個の数字のうち 8 個が素数であることです。その割合は 8/13 ≈ 62% です。

このらせんの周りに完全な 1 層を新たに加えると、辺の長さが 9 の正方形のらせんになります。 この処理を続けた場合に、両方の対角線上の素数の割合が最初に percent を下回るような正方形のらせんの辺長を求めなさい。

--hints--

spiralPrimes(50) は数値を返す必要があります。

assert(typeof spiralPrimes(50) === 'number');

spiralPrimes(50)11 を返す必要があります。

assert.strictEqual(spiralPrimes(50), 11);

spiralPrimes(15)981 を返す必要があります。

assert.strictEqual(spiralPrimes(15), 981);

spiralPrimes(10)26241 を返す必要があります。

assert.strictEqual(spiralPrimes(10), 26241);

--seed--

--seed-contents--

function spiralPrimes(percent) {

  return true;
}

spiralPrimes(50);

--solutions--

function spiralPrimes(percent) {
  function isPrime(n) {
    if (n <= 3) {
      return n > 1;
    } else if (n % 2 === 0 || n % 3 === 0) {
      return false;
    }

    for (let i = 5; i * i <= n; i += 6) {
      if (n % i === 0 || n % (i + 2) === 0) {
        return false;
      }
    }
    return true;
  }

  let totalCount = 1;
  let primesCount = 0;
  let curNumber = 1;
  let curSideLength = 1;
  let ratio = 1;
  const wantedRatio = percent / 100;

  while (ratio >= wantedRatio) {
    curSideLength += 2;
    for (let i = 0; i < 4; i++) {
      curNumber += curSideLength - 1;
      totalCount++;
      if (i !== 3 && isPrime(curNumber)) {
        primesCount++;
      }
    }
    ratio = primesCount / totalCount;
  }
  return curSideLength;
}