13日目 エラトステネスの篩(ふるい)を知ってますか?【30日間1日1本マクロ生活】
30日間1日1本マクロ生活、13日目です。
マクロを書く準備は、0日目に記事を書きました。
エラトステネスの篩
中学校や高校の数学で、エラトステネスの篩について学習しませんでしたか?
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
1から30までの整数を表にしてみました。
まず1を消します。
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
次に2を残し、それ以外の2の倍数をすべて消します。
2 | 3 | 5 | 7 | 9 | ||||
11 | 13 | 15 | 17 | 19 | ||||
21 | 23 | 25 | 27 | 29 |
2の次の数は3です。3を残し、3の倍数をすべて消します。
2 | 3 | 5 | 7 | |||||
11 | 13 | 17 | 19 | |||||
23 | 25 | 29 |
3の次は4ですが、すでに4が消えています。その次は5です。
この5は、2の倍数でも3の倍数でもなかったから残っています。
つまり、自分よりも小さい数では、絶対に割り切れなかったから残った数です。
このような数を「素数」と言います。
5を残し、5の倍数をすべて消します。
2 | 3 | 5 | 7 | |||||
11 | 13 | 17 | 19 | |||||
23 | 29 |
この最後の表に残った数は、すべて素数です。
1と自分自身以外では割り切ることのできない数です。
この一連の操作のことを「エラトステネスの篩」といいます。
今日はこれをマクロでやってみます。
1から100までの数を表にしています。
エラトステネスの篩で素数だけにしてみましょう。
さっそくコードを
Sub エラトステネスの篩()
For Each c In Range(Cells(1, 1), Cells(17, 6))
If c = 1 Then c.ClearContents
If c Mod 2 = 0 And c <> 2 Then c.ClearContents
If c Mod 3 = 0 And c <> 3 Then c.ClearContents
If c Mod 5 = 0 And c <> 5 Then c.ClearContents
If c Mod 7 = 0 And c <> 7 Then c.ClearContents
Next c
End Sub
では、解説します。
Range
2行目のFor Eachは1日目にやりました。
その後ろの「Range」について。
「Range(セル,セル)」で、指定したセルとセルを対角線の両端とする長方形の範囲を表します。
ここでは左上のCells(1,1)から右下のCells(17,6)までの長方形を範囲として、そのすべてのセルcについてループを回します。
ClearContents
セルの値が1のときは、そのセルをClearContentsします。
ClearContentsとは、そのセルの内容を消去してしまう命令です。「DEL」キーを押すのと同じですね。
セルの値を2で割った余りが0、つまり2の倍数で、かつ、そのセルの値が2ではない場合、ClearContentsです。
セルの値を3で割った余りが0、つまり3の倍数で、かつ、そのセルの値が3ではない場合、ClearContentsです。
セルの値を5で割った余りが0、つまり5の倍数で、かつ、そのセルの値が5ではない場合、ClearContentsです。
セルの値を7で割った余りが0、つまり7の倍数で、かつ、そのセルの値が7ではない場合、ClearContentsです。
これを指定したRange内の全てのセルについてやります。
次の素数は11
次の素数は11です。
11の倍数を全て消すことはしなくてもいいんです。
なぜかというと、
- 11は消さない。素数だから。
- 11×2は、2の倍数だからすでに消えてる。
- 11×3は、3の倍数だからすでに消えてる。
- 11×4は、2の倍数だからすでに消えてる。
- 11×5は、5の倍数だからすでに消えてる。
- 11×6は、2の倍数だからすでに消えてる。
- 11×7は、7の倍数だからすでに消えてる。
- 11×8は、2の倍数だからすでに消えてる。
- 11×9は、3の倍数だからすでに消えてる。
- 11×10は110だから、100を超えてるのでこの表の中に無い。
ということなんです。それ以上の数についても同じ。
だから、この表から消える数はもうありません。
エラトステネスの篩の完了です。
実行結果
マクロを記述するウィンドウの「Sub」と「End Sub」の間にカーソルを置いて、画面上方の再生ボタン的なアイコン(右向きの三角形)をクリックするか、[F5]キーを押します。
このように、素数だけが残りました。
素数の判定
素数って、すごく奥が深いんですよね。
与えられた自然数が素数なのかどうかを判定するには、エラトステネスの篩を応用させるしかないんです。
素数だけが残った表、よく見てください。
12日目の結果と何か関係がありそうじゃないですか?
Excelは便利
悔しいですが、Excelは便利です。
Microsoftにお金を払うのは癪でしょうがないんですが、Excelばかりは仕方がない。
マクロを書くようになると、Excelからは離れられないですね。
30日間、頑張ります。