素数大学《素数判定》

素数メニュー【エラトステネスの篩・グロタンディーク素数・フェルマーテスト・素数判定・大きな数の素数判定・素数大学】

【グロタンディーク素数】コード

const n = 57;
let prime = true;  // 素数か否かの真偽値を true で初期化
for (let i = 2; i * i <= n; i++) {  // ループの範囲は 2 ~ n の平方根
// for (let i = 2; i <= Math.sqrt(n); i++) {
   if (n % i === 0) {  // ni で割り切れれば…
      prime = false;  // n は 素数に該当しないので prime は false
      break;
   }
}
console.log(prime ? 'YES' : 'NO');
hogeちゃんの画像

57 は 3 で割り切れるので 素数じゃなかった。

【素数判定】コード

reader.on('close', () => {
   const N = Number(lines[0]);
   let prime = true;  // 素数か否かの真偽値を true で初期化
   if (N === 1) {  // N が 1 の場合…
      prime = false;  // 素数に該当しない(例外処理)
   }
   for (let i = 2; i * i <= N; i++) {  // ループの範囲は 2 ~ N の平方根
// for (let i = 2; i <= Math.sqrt(N); i++) {
      if (N % i === 0) {  // Ni で割り切れれば…
         prime = false;  // N は 素数に該当しないので prime は false
         break;
      }
   }
   console.log(prime ? 'YES' : 'NO');
});
hogeちゃんの画像

N の値を入力から受け取っていますが 【STEP: 1】と ほぼ 同じです。

【大きな数の素数判定】コード

reader.on('close', () => {
   const N = Number(lines[0]);
   let prime = true;
   if (N === 1) {  // N が 1 の場合…
      prime = false;  // 素数に該当しない(例外処理)
   }
   for (let i = 2; i * i <= N; i++) {  // ループの範囲は 2 ~ N の平方根
// for (let i = 2; i <= Math.sqrt(N); i++) { 
      if (N % i === 0) {  // Ni で割り切れれば…
         prime = false;  // N は 素数に該当しないので prime は false
         break;
      }
   }
   console.log(prime ? 'YES' : 'NO');
});
hogeちゃんの画像

大きな数になっても【STEP: 2】と同じコードで通過できました。

(´・∀・)?

【エラトステネスの篩】コード

reader.on('close', () => {
   const N = Number(lines[0]);
   const prime = new Array(N + 1).fill(true);  // 0 ~ N の素数か否かをtrueで初期化
   [prime[0], prime[1]] = [false, false];  // 0 と 1 は 2 以下なので素数に該当しない
   for (let i = 2; i * i <= N; i++) {  // ループの範囲は 2 ~ N の平方根
   // for (let i = 2; i <= Math.sqrt(N); i++) {
      if(!prime[N]){  // prime[N] が 素数に該当しないことがわかっていれば…
         break;  // 処理を止める
      }
      if (prime[i]) {  // prime[i]が初期値(true)のときのみ実行
         for (let j = 2; j * i <= N; j++) {  // j * iN 以下の間 ループ
            prime[i * j] = false;  // 2つの値を乗算した値は素数に該当しない
         }
      }
   }
   console.log(prime[N] ? 'YES' : 'NO');
});
hogeちゃんの画像
素数判定の漸化式バージョンですね。

【フェルマーテスト】コード

reader.on('close', () => {
   const N = Number(lines[0]);  
   const a = 2;  // 2 ~ N-1 の範囲内の数値 → 2に設定
   let fermat = 1;  // fermat (a^(N-1) % N を求めるための変数)を1で初期化
   let prime = true;
   if (N % a === 0) {  // Na で割り切れる場合
      prime = false;  // N は素数に該当しない
   }
  // a^(N-1) % N を求めるためのループ(fermat * a % NN - 1 回 繰り返す)
   for (let i = 1; i < N; i++) {
      fermat = fermat * a % N;
   }
   if (fermat % N !== 1) {  // a^(N-1) % N が 1 でない場合
      prime = false;  // N は素数に該当しない
   }
   console.log(prime ? 'YES' : 'NO');
});
hogeちゃんの画像

フェルマーテスト…。整数 N が素数であるかを高確率で判定する方法の 1 つ。だそうです。

【素数大学】コード

reader.on('close', () => {
   const N = Number(lines[0]);  // 受験者数
   const A = [];  // 受験番号(素数なら合格)
   for (let i = 1; i <= N; i++) {
      A.push(Number(lines[i]));  // A に 受験番号を保存
   }
// エラトステネスの篩 ここから
   const M = Math.max(...A);  // 受験番号の最大番号
   const prime = new Array(M + 1).fill(true);  // 受験番号の最大番号までの素数であるかどうかの真偽値
   [prime[0], prime[1]] = [false, false];  // 2 以下は素数に該当しないので false
   for (let i = 2; i * i <= M; i++) {  // ループの範囲は 2 ~ M の平方根
   // for (let i = 2; i <= Math.sqrt(M); i++) {
      if (prime[i]) {  // prime[i]が初期値(true)のときのみ実行
         for (let j = 2; j * i <= M; j++) {  //  j * iN 以上になるまで ループ
            prime[i * j] = false;  // 2つの値をかけ合わせた値は素数に該当しない
         }
      }
   }
// エラトステネスの篩 ここまで
   A.forEach(a => {
      console.log(prime[a] ? 'pass' : 'failure');
   });
});
hogeちゃんの画像

あらかじめ primeに 0〜A の最大値 までの素数であるかどうかの真偽値を保存して エラトステネスの篩で処理。forEach()A の各値が素数に該当するかどうかを出力しています。

コメント