Edited at

2019年の素数になる日を求めて人生に備える


はじめに

2019年Qiita初めです。

何番煎じかわかりませんが、日付が素数になる日を求めて表示するプログラムの2019年バージョンです。

言語特有の書き方ができそうだなと思ったのでちょっと書いてみました。


ルール


  • 2019年の日付について、日付を8桁整数として扱い素数かどうかを判定、素数であれば画面表示します。



    • yyyyMMddというやつです。


    • 2019/01/0120190101 です



  • 最終的に何日素数になる日があるかを最終行に出力します。


結果


  • オンラインエディタで出力を見れるようにしました。



  • 素数である日


    • 2019-02-21

    • 2019-02-27

    • 2019-03-01

    • 2019-03-19

    • 2019-03-23

    • 2019-04-21

    • 2019-05-23

    • 2019-05-29

    • 2019-06-01

    • 2019-06-13

    • 2019-07-19

    • 2019-08-11

    • 2019-08-23

    • 2019-09-13

    • 2019-10-09

    • 2019-10-27

    • 2019-11-09

    • 2019-11-17

    • 2019-12-31



  • 2019年に素数となる日は19日あります。

  • なんと2019年の大晦日、20191231は素数です!


実装

D言語で書きました。

シングルファイル形式なので、そのまま適当なファイルにコピペして dub run --single app.d で動きます。

またはオンラインエディターで実行結果のほうでも確認できます。

https://run.dlang.io/is/fqNZDq


素朴な書き方

/++ dub.sdl: +/

import std.experimental.all;

void main()
{
auto current = Date(2019, 1, 1);
auto end = Date(2019, 12, 31);
size_t total = 0;

while (current <= end)
{
auto n = toNum(current);
if (isPrime(n))
{
total++;
writeln(current.toISOExtString());
}

current += 1.days;
}

writeln("Total: ", total);
}

int toNum(Date date)
{
return date.year * 10000 + date.month * 100 + date.day;
}

bool isPrime(int n)
{
for (int i = 2; i * i <= n; i++)
{
if (n % i == 0) return false;
}
return true;
}


日付範囲をRangeで扱うバージョン

D言語ではstd.datetime.interval というモジュールがあり、日付の列挙も簡単で柔軟です。

/++ dub.sdl: +/

import std.experimental.all;

void main()
{
auto interval = Interval!Date(Date(2019, 1, 1), Date(2020, 1, 1)).fwdRange(date => date + 1.days);
size_t total = 0;

foreach (current; interval)
{
auto n = toNum(current);
if (isPrime(n))
{
total++;
writeln(current.toISOExtString());
}
}

writeln("Total: ", total);
}

int toNum(Date date)
{
return date.year * 10000 + date.month * 100 + date.day;
}

bool isPrime(int n)
{
for (int i = 2; i * i <= n; i++)
{
if (n % i == 0)
return false;
}
return true;
}


最後に

プログラミングたのしい!

誰かワンライナー版書いてくれませんかー