LoginSignup
5

More than 3 years have passed since last update.

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

Last updated at Posted at 2015-12-01

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

素数日とは

素数日とは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(2025, 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

2020-12-31
2021-01-01

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

まとめ

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5