七五三とポッキーの日と素数

## はじめに

こんにちは。ひよこまんじゅう大好きひよこ🐣です。

今日は  11月 15 日、そう七五三ですね！ 女の子が三歳と七歳、男の子が五歳にお祝いをする行事ですが、最近の世の中では性別に関係なくお祝いするようです。そんな七五三から私が思い浮かべるのは「素数」の並びです。そこで今回は素数についてのお話をしてみたいと思います。

> 🐣 ただし、私は数学は専門外ですので、あたたかい目で読んでいただけると嬉しいです

---

## 七五三と素数

偶数の素数は 2 だけなので、2 と 3 以外の素数の差は必ず 2 以上になります。このうち差が 2 の素数のペアを **双子素数** と呼びます。例えば、3 と 5、11 と 13 がその例ですね。

双子素数が無限に存在するかどうかは、いまだに解かれていない数学の未解決問題なのだそうです。一方で、七五三の「7、5、3」のように素数が三つ並ぶことを **三つ子素数** と考えるとどうでしょうか？

実は、三つ子素数として認められるのは $(3, 5, 7)$ だけです。なぜでしょうか？ それは、3 を越える素数が $3k+1$ または $3k+2$ の形で表されるためです。もしこの形の数を使って三つ子を作ろうとすると、次のようになります。

```math
3k+1, \ 3k+3=3(k+1), \ 3k+5 \\
3k'+2, \ 3k'+4, \ 3k'+6=3(k'+2)
```

このように、どちらの場合も 3 の倍数が含まれてしまい、素数ではなくなります。七五三が三つ子素数といえるのは、唯一 3 を含んでいるからこそ成り立つ特別なケースなのです。

このため、一部では $(p, p+2, p+6)$ や $(p, p+4, p+6)$ を三つ子素数と定義する場合もあるそうです。

---

## 七五三と AI の進化

七五三にちなんで、AI 分野の進化を振り返ってみました。

- **7 年前 (2017 年)**  
  Transformer の登場！ あの有名な論文 *Attention is All You Need* が発表されましたね。
  
- **5 年前 (2019 年)**  
  BERT が登場しました。自然言語処理において、大きな進化を遂げた年ですね。(※ 厳密には BERT の発表は 2018 年末ですが、大ブレークしたのは 2019 年頃です)

- **3 年前 (2021 年)**  
  DALL-E 2 や CLIP など、画像生成 AI が急速に発展した年です。

こうしてみると AI の進化は早いですね。3 年先、5年先、7年先が楽しみやら恐ろしいやら…

## ポッキーの日
そういえば、今週は 11 月 11 日 つまりポッキーの日がありました。

> 🐣 正式名称はポッキー＆プリッツの日というらしいですが…

七五三ではあまり話題が膨らまなかったので、「1」がたくさん並んだポッキーの日にちなんで、レピュニット素数についても書いてみたいと思います。

---

## レピュニット素数とは？

レピュニット数とは、1 が繰り返し並んだ数のことです。例えば、

- 1 桁: 1
- 2 桁: 11
- 3 桁: 111
- 4 桁: 1111

という形です。英語で書くと repunit、つまり repeated unit (単位の繰り返し) という意味が語源なのだそうです。これを一般式で表すと、

```math 
R_n = \frac{10^n - 1}{9} 
```

と書けます。ここで $R_n$ は n 桁のレピュニット数を表します。この中で素数であるものをレピュニット素数と呼びます。

---

## レピュニット素数を探してみる

### 1200 桁までの探索方法

レピュニット数は単純そうに見えて、桁数が大きくなると計算が大変です。そこで以下の 3 つの方法を試してみました。

1. **文字列 "1" を $n$ 回繰り返して整数化**
2. **ループで前回の値に $10^{n-1}$ を足す**
3. **公式 $R_n = \frac{10^n - 1}{9} = \frac{(10 - 1)(10^{n-1} + 10^{n-2} + \dots + 1)}{9}$ を使う**

結論から言うと、記憶変数を使っていいなら 2. が一番効率的でした。単発で計算するなら 3．の方がよさそうですけどね。以下は Python で 1200 桁までのレピュニット数を生成し、素数判定したコードです。結構大きな数になるので、数学ライブラリ sympy の isprime で判定しています。

```python
import sympy

num = 1
for i in range(1, 1200):
    if sympy.isprime(num):
        print(i, num)
    num += 10**i
```

この結果、以下の桁数でレピュニット素数が見つかりました。

- $n = 2$: 11
- $n = 19$: 111...111（19 桁）
- $n = 23$: 1111...1111（23 桁）
- $n = 317$: 11111...11111（317 桁）
- $n = 1031$: 1111111...1111111（1031 桁）

案外少ないですね… 

> 🐣 1031 は天才っぽくていいかも

これより大きいレピュニット素数で現在確定しているのは $n = 49081$ の場合だけです。
$n=109297, 270343, 579477, 817720$ の場合もおそらくレピュニット素数だと言われていますが確定はしていないそうです。素数かどうかを調べるだけでも大変な作業ということですね…
数学的にはレピュニット素数が無限に存在するか？は双子素数と同じく未解決問題みたいです。

---

## レピュニット素数の数学的性質

### なぜレピュニット数は素数になりにくい？

レピュニット数 $R_n$ が素数になるのは非常に稀です。その理由の一つは、桁数 $n$ が素数であるときにしか $R_n$ は素数にならないからです。
例えば、$n = 4$ の場合、$R_4 = 1111 = 11 × 101$ となり合成数です。一方で $n = 19$ や $n = 23$ のように桁数が素数のときは、$R_n$ が素数になる可能性がありますが、桁数が素数だからと言って必ずしも $R_n$ が素数になるわけではありません。
先ほどのコード例では愚直に計算していますが、この性質を利用して桁数が素数のときだけ判定するように改良することができます。

> 🐣 111 って素数っぽく見えませんか？ 各桁の和が 3 なので 3 で割れちゃうんですけどね

---

## レピュニット素数の拡張

レピュニット数は 10 進法だけでなく、他の進法でも考えることができます。例えば 2 進法表記のレピュニット数を 10 進法に直すと以下のようになります。

- 2 進法: 1, 11, 111, 1111...
- 10 進法: 1, 3, 7, 15...

進法を変えると、素数になる条件も変わります。というわけで 2 進法から 9 進法までのレピュニット数を生成し、素数判定をしてみました。

```python
import sympy

num = 1
result = [0] * 8  # 2進法から9進法までの結果を格納
for i in range(1, 1200):
    for N in range(2, 10): # N 進法
        num_N = int(str(num), N) # int を使うと簡単に N 進法に変換できる
        if sympy.isprime(num_N):
            print(f"num={i}, {N} 進法, value={num_N}")
            result[N - 2] += 1 # N 進数ごとに何回素数になったか保持
    num += 10**i
print(result)
```

### 結果

1200 桁以下でそれぞれの進法において見つかったレピュニット素数の数は以下の通りでした。

- 2 進法: 14 個
- 3 進法: 7 個
- 4 進法: 1 個
- 5 進法: 10 個
- 6 進法: 9 個
- 7 進法: 4 個
- 8 進法: 1 個
- 9 進法: 0 個

基数 2 で多くの素数が見つかる理由は、これがメルセンヌ数に対応しているためです。一方で、基数 9 では素数が見つかりませんでした。一般に $N$ が平方数の場合のレピュニット数が素数になることはありません。例外は 4 進法表記の 11 (=5) だけになります。また 10 進数では 3 で簡単に割れてしまう 111 ですが、2, 3, 5, 6, 8 進数表記では全部素数になります！

> 🐣 111 が素数っぽいという感覚は実は悪くなかったのかも！？

また、1111111111111 は 3,5,7 つまり七五三進数すべてで素数になります！


## メルセンヌ素数

基数 2 の場合 $10^p$ の形が 2 の $p$ 乗に対応するので、ここから 1 を引いた形の 2 進数表記のレピュニット数は 10 進数だと以下のメルセンヌ数になります。

```math
M_p = 2^p - 1
```

メルセンヌ素数にはリュカーレーマーテストというチート級に優れた素数の判定法があるので、巨大な素数といえばそれはほぼメルセンヌ素数のことです。この形ではない素数の判定は非常に難しいというわけです。 一般の素数に対してはミラー・ラビン法と呼ばれる素数判定法が有名ですが、これは**確率的なテスト**なのでパスしたからといっても必ず素数だと断定はできません。
2024 年 10 月 26 日にも新しいメルセンヌ素数の発見が話題になっていましたね。この素数の桁数はおよそ 4,100 万桁にも達するそうです。

[NHKニュース「新しい素数が発見」](https://www3.nhk.or.jp/news/html/20241026/k10014619781000.html)

---
## 七五三とポッキーの日と素数

最後に七五三とポッキーの日にちなんで、753 のあとに $R_n$ が続く形で素数になる数を次のコードで探してみました。
数字は文字列を作ってから int に変換しています。

```python
import sympy

for i in range(1,1200):
    rep="1"* i
    num=int("753"+rep)
    if(sympy.isprime(num)):
        print(i,num)
```

その結果、以下のような素数が見つかりました。

1. $7531...1$ (1 が 47 個)
2. $75311...11$ (1 が 140 個)
3. $7531111...1111$ (1 が 701 個)

$n=1200$ まで調べた結果、この形の素数はこの 3 つだけでした。

> 🐣 これを 七五三ポッキー素数と命名しちゃいます！

---

## おわりに

11月の数字イベント七五三とポッキーの日にちなんで、素数についていろいろ考えてみました。あまり数学が得意ではない私でも、ちょっとだけ数学の深淵に触れた気分になれるので素数の話は大好きです。この機会にぜひ、数学の楽しさに触れてみてください！