🐣

ポッキーの日といえば? そうだ、レピュニット素数の話をしよう!

2024/11/11に公開

はじめに

こんにちは。お菓子大好きひよこ🐣です。
今日は 11 月 11 日、ポッキーの日ですね!「1」がたくさん並んだこの日にちなんで、レピュニット素数について書いてみたいと思います。ポッキーでも食べながら数学のちょっとした話題として楽しんでいただければ幸いです。


レピュニット素数とは?

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

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

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

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

と書けます。ここで R_n は n 桁のレピュニット数を表します。この中で素数であるものをレピュニット素数と呼びます。
今日 11/11 はポッキーの日なので、この 1111 にちなんでみようというわけです。


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

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 で判定しています。

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 = 19n = 23 のように桁数が素数のときは、R_n が素数になる可能性がありますが、桁数が素数だからと言って必ず R_n が素数になるわけではありません。
先ほどのコード例では愚直に計算していますが、この性質を利用して桁数が素数のときだけ判定するように改良することができます。

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


N 進法でのレピュニット素数

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

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

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

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 が素数っぽいという感覚は実は悪くなかったのかも!?

メルセンヌ素数

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

M_p = 2^p - 1

巨大な素数の発見は、世界に愛好家がいる人気?分野です。
メルセンヌ素数にはリュカ–レーマーテストというチート級に優れた素数の判定法があるので、巨大な素数といえばそれはほぼメルセンヌ素数のことです。つまり、発見されているメルセンヌ素数たちの間にはまだまだたくさんの素数があるはずなのですが、判定法がないので発見されることなくお宝のように埋まっているというわけです。

🐣 判定待ちのレピュニット素数候補もこれですね

2024 年 10 月 26 日にも新しいメルセンヌ素数の発見が話題になっていましたね。この素数の桁数はおよそ 4,100 万桁にも達するそうです。

NHKニュース「新しい素数が発見」


2024 年ポッキーの日にちなむ素数

最後に 2024 年にちなんで、2024 + R_n の形で素数になるものを次のコードで探してみました。
数字は文字列を作ってから int に変換しています。

import sympy

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

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

  1. 2024111 (1 が 3 個)
  2. 2024111111111111111111111111111 (1 が 27 個)
  3. 2024111111111111111111111111111111111 (1 が 33 個)

n=1200 まで調べても素数はこの 3 つだけでした。

🐣 これを 2024年ポッキー素数と命名しちゃいます!


おわりに

ポッキーの日にちなんで、レピュニット素数について考えてみました。あまり数学が得意ではない私でも、ちょっとだけ数学の深淵に触れた気分になれるので素数の話は大好きです。この機会にぜひ、数学の楽しさに触れてみてください!

それでは、また次回の記事でお会いしましょう!

Discussion