「素数の日」で検索すると、西暦+月+日の8桁の自然数が素数になる日を素数の日と呼ぶ結果が多くみつかります。面白い考えですが、記念日は、毎年1回ある方が祝いやすいです。3桁または、4桁の素数を考えてみました。
最初に結論
12月23日を4桁の数字 1223 と考えると、それ自身が素数です。また左から桁を消していくと得られる 223 も 23 も 3 もすべて素数になります。
言い換えると、日付として、
1223は、唯一の4桁の左切り捨て可能素数
です。
切り捨て可能な素数は、この記事で定義や例を紹介しました。
プログラム(C言語)の紹介
途中の桁に0を含む場合は、左切り捨て可能素数と呼びません。ただし、以下のプログラムでは、候補として0を含む素数も出力しています。
ソースコードは、以下から流用しました。
- 素数か判定する is_prime : 整数の道具箱から
- 左切り捨て可能素数か判定する関数 is_satisfied : Projec Euler 問題37から
- 毎月の日数の配列は day_table : Project Euler 問題19から
月+日の数で左切り捨て可能な素数を出力する C プログラムは以下となります。
#include <stdio.h>
int daytable [2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
int is_prime(int n)
{
int answer = 1;
int i;
if (n <= 1) {
answer = 0;
}
for (i = 2; i * i <= n; ++i) {
if (n % i == 0) {
answer = 0;
break;
}
}
return answer;
}
int is_satisfied(int number)
{
int ret_val = 1;
int mask, check_number;
mask = 1000;
if (is_prime(number) == 0) {
ret_val = 0;
}
check_number = number % mask;
while (mask >= 10) {
if (is_prime(check_number) == 0) {
ret_val = 0;
break;
}
mask = mask / 10;
check_number = number % mask;
}
return ret_val;
}
int main(void)
{
int month, day;
int date;
for (month = 1; month <= 12; ++month) {
for (day = 1; day <= daytable[1][month - 1]; ++day) {
date = month * 100 + day;
if (is_satisfied(date) == 1) {
printf("%4d\n", date);
}
}
}
return 0;
}
出力は、以下となります。
103
107
113
223
307
313
317
503
523
607
613
617
823
907
1013
1103
1223
0を含まない4桁の左切り捨て可能な素数は、1223 だけであることが分かります。
なお、左切り捨て可能素数である、313 と 317 は、右切り捨て可能素数にもなっています。実際、317 の右の桁を消した 31 と 3 も素数になっています。
最後に
「1223 は、下の桁の 3、23、223、1223 が、すべて素数になっています。このような数は、1223 だけです。だから、12月23日を素数の日と呼ぶのはどうでしょうか」という内容でした
プログラムで計算して、このようなことが分かると楽しくなります。
≪…1223 は、下の桁の 3、23、223、1223 が、すべて素数になっています。…≫から、自然数としての数の言葉ヒフミヨ(1234)で眺めると円環の2等分からの直線(直径)の2等分で半径、そして、円環の3等分による正三角形が、数直線の向き(+ -)を決めていると・・・
このモノたちは[素]に観えてくる。