見出し画像

Excelで双子素数探索(算術級数定理)

ある朝目覚めると、首が痛かった。
寝違えたらしい・・・。
ほっとけば直るかと思っていたが、翌日さらに悪化した^^;
整形外科へ行って、注射してもらって、痛み止めと固まった筋肉をほぐす薬をもらい飲み続けているけれど、まだ完治していない。
レントゲン見たら完全なストレートネックだった・・・。
スマホ見すぎかな?


ディリクレの算術級数定理

算術級数定理(さんじゅつきゅうすうていり、theorem on arithmetic progressions)は、初項と公差が互いに素である算術級数(等差数列)には無限に素数が存在する、という定理である。ペーター・グスタフ・ディリクレが1837年にディリクレのL関数を用いて初めて証明した。そのため、定理はしばしばディリクレの算術級数定理と呼ばれる。

定理の言い換えとして、gcd(a,b)=1である自然数 a, b に対し、an+b (n は自然数)と書ける素数が無限に存在する、としてもよい。

Wikipedia「算術級数定理」

なにやら難しいこと言ってますが、この定理から導かれることとして、$${a=10}$$とした場合、$${1,3,7,9}$$は$${a}$$と互いに素なので、$${10n+1,10n+3,10n+7,10n+9}$$で表すことのできる素数が無限に存在する、ということ。
では、実際にどのような割合で素数が分布しているのか調べてみましょう。

100万以下の素数の分布

いつものごとくワンライナーで、とも思ったのですが、重くて動かなかったので、普通にカウントしてみました。

100万以下の素数分布

1,3,7,9の4つに見事に分かれていますね。
こんな不思議現象が証明されているってすごいですね。

双子素数の分布

では、双子素数ならどうなっているのかを見てみたいところですが、100万だと計算が終わらなかったので、10万で妥協しました。
双子素数リスト生成コード。

=LET(
    _max, 10000,
    _1_, "_max以下の素数列を生成",
    _primes, LET(
        _1_, "基本素数 base prime",
        _bp, {2; 3; 5; 7},
        _2_, "内部再帰関数 F:自分自身",
        _F, LAMBDA(F, n,
            LET(
                _1_, "√n以下の素数で試し割りすれば良いので√nを算出",
                _sq, SQRT(n),
                _2_, "試し割用素数列 test prime",
                _3_, "_sqが11より小さければ_bpから値を返す。大きければ再帰して値を求める",
                _tp, IF(_sq < 11, FILTER(_bp, _bp <= _sq), F(F, _sq)),
                _4_, "_tpの最後の値を取得 Terminate test prime",
                _ttp, @TAKE(_tp, -1),
                _5_, "_ttp+1~nの数字を_tpで試し割して、割り切れない数字だけ残す",
                _re, REDUCE(
                    SEQUENCE(n - _ttp, , _ttp + 1),
                    _tp,
                    LAMBDA(a, s, TOCOL(IF(MOD(a, s), a, NA()), 2))
                ),
                _6_, "_tpと_reを結合",
                VSTACK(_tp, _re)
            )
        ),
        _3_, "実行",
        _F(_F, _max)
    ),
    _2_, "6nの数列のうち、前後が素数である数だけ抜き出し。Twin Prime Centers",
    _tpcenters, LET(
        _r, SEQUENCE(_max / 6, , 6, 6),
        _z, FILTER(
            _r,
            ISNUMBER(XMATCH(_r - 1, _primes, FALSE)) *
                ISNUMBER(XMATCH(_r + 1, _primes, FALSE))
        ),
        _z
    ),
    _3_, "双子素数",
    REDUCE({2; 3}, _tpcenters, LAMBDA(a, s, VSTACK(a, VSTACK(s - 1, s + 1))))
)

今回載せるコードはこれだけです。
目新しいことしていないのに、処理時間だけかかってしまっているので、今回は結果だけ載せていきます。
算出した双子素数の1の位をカウントしたのがこちら。

双子素数分布(10万以下)

予想はしていました。
5の倍数が素数にならないので、$${(3,5),(5,7)}$$の双子素数ペアができないわけだから、1と9が多くなるだろうと。
ペアごとにカウントしてみるとこうなる。

双子素数ペア(10万以下)

これまた見事に揃ってる。
こんなにも偏りが無いのが逆に不思議。
一応、双子素数中心数をカウントしてみたのがこちら。

双子素数中心数(10万以下)

まぁ、そうだよね。
違ってたらバグだよね。

勉強結果

今回はここまで。
ファイルも整理されていないので、アップはありません。
素数の分布は不規則すぎて規則正しいって本当にすごい。

いいなと思ったら応援しよう!