Help us understand the problem. What is going on with this article?

8桁表示で素数日や連続素数日を探す

More than 3 years have passed since last update.

よく「今日は素数の日だ」なんて話を聞いて気になったので探してみることにしました。

素数日とは

素数日とはyyyymmddで数値にした時に素数となる日付のことと定義します。
例えば2015年11月27日は20151127が素数なので素数日です。

素数は無限にありますので、素数日も無限にあると期待されます。

普通に探す

とりあえず2015年の素数日を探してみましょう。
こんな感じでしょうか?

require 'prime'
require 'date'

puts [*Date.new(2015, 1, 1).upto(Date.new(2015, 12, 31))].flat_map{|d|
    Prime.prime?(d.strftime('%Y%m%d').to_i) ? [d.to_s] : []
}
2015-01-11
2015-01-31
2015-02-27
2015-03-03
2015-03-27
2015-04-11
2015-05-13
2015-08-21
2015-10-11
2015-10-31
2015-11-27
2015-12-21
2015-12-27

13日、意外と少ないです。実はここ100年では1923年と並んで素数日の数が最小の年なんですね。(明日使える豆知識1)
多い時は30日以上あるのでかなり偏っていることがうかがえます。

双子素数日

ところで、双子素数といって、差が2の素数の組はよく研究対象になります。というわけで差が2日の双子素数日を探してみましょう。

require 'prime'
require 'date'

[*Date.new(2015, 1, 1).upto(Date.new(2020, 12, 31))].flat_map{|d|
    Prime.prime?(d.strftime('%Y%m%d').to_i) ? [d] : []
}.each_cons(2) {|d1, d2|
    puts d1, d2, "\n" if (d2-d1).to_i == 2
}
2016-04-01
2016-04-03

2016-10-19
2016-10-21

2017-03-01
2017-03-03

2017-09-01
2017-09-03

2019-02-27
2019-03-01

2020-01-09
2020-01-11

2020-01-21
2020-01-23

2020-07-21
2020-07-23

思ったよりありますね。ちなみに双子素数が無限にあるかどうかは未解決問題なので、双子素数日も無限にあるかどうかは不明です。月またぎでイレギュラーなものもあるのでなんとも言えませんが…

三つ子素数日

さらに三つ子素数というものを考えてみます。三つ子素数とは(p, p+2, p+6)または(p, p+4, p+6)の形のもので、(p, p+2, p+4)の形ではありません。なぜならばこの場合、必ず3の倍数を含むからです。

しかしながら、(当日・2日後・4日後)という素数日は存在の可能性があります。月や年の変わり目を含めば良いからです。

require 'prime'
require 'date'

[*Date.new(2015, 1, 1).upto(Date.new(2100, 12, 31))].flat_map{|d|
    Prime.prime?(d.strftime('%Y%m%d').to_i) ? [d] : []
}.each_cons(3) {|d1, d2, d3|
    if (d2-d1).to_i == 2 && (d3-d2).to_i == 2
        puts d1, d2, d3, "\n"
    end
}
2085-06-29
2085-07-01
2085-07-03

2087-04-29
2087-05-01
2087-05-03

というわけで、残念ながら次は2085年のようなので生きてるうちには拝めなさそうです(明日使える豆知識2)。

最後にタイトルにある連続素数日ですが、これも素数の場合は普通にはありませんね。(n, n+1)は必ずどちらかが2の倍数だからです。しかし、素数日の場合は月や年をまたげるのでした。31日(or2月29日)だけ起こる可能性があります。

require 'prime'
require 'date'

[*Date.new(2015, 1, 1).upto(Date.new(2020, 12, 31))].flat_map{|d|
    Prime.prime?(d.strftime('%Y%m%d').to_i) ? [d] : []
}.each_cons(2) {|d1, d2|
    puts d1, d2, "\n" if (d2-d1).to_i == 1
}
2017-08-31
2017-09-01

2018-07-31
2018-08-01

というわけで、次は2017年らしいです。ちなみに20201231-20210101は年をまたいだ連続素数日になります。これは1987-88シーズン以来33年ぶりの出来事です。(明日使える豆知識3)

まとめ

素数日、というものを定義して簡単に分布を調べてみました。結構多いなというのが印象です。コードとしては偶数の日を調べる必要はないし、最後の方はすべての日付を調べる必要がないので、もうちょっと高速に探す方法に直せそうです。

ytkhs
A web developer based in Tokyo, Yokohama and Niigata.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away