--- id: 5900f3a61000cf542c50feb9 title: '問題 58: らせん素数' challengeType: 5 forumTopicId: 302169 dashedName: 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)` は数値を返す必要があります。 ```js assert(typeof spiralPrimes(50) === 'number'); ``` `spiralPrimes(50)` は `11` を返す必要があります。 ```js assert.strictEqual(spiralPrimes(50), 11); ``` `spiralPrimes(15)` は `981` を返す必要があります。 ```js assert.strictEqual(spiralPrimes(15), 981); ``` `spiralPrimes(10)` は `26241` を返す必要があります。 ```js assert.strictEqual(spiralPrimes(10), 26241); ``` # --seed-- ## --seed-contents-- ```js function spiralPrimes(percent) { return true; } spiralPrimes(50); ``` # --solutions-- ```js 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; } ```