Project Euler の問題を解くためにプログラムした関数は、今後も使用できそうです。整数に関する関数は別の記事にまとめました。今回は、カレンダーと順列、その他に関する関数を紹介します。
曜日判定
年月日を与えると、曜日を返す関数です。グレゴリオ暦(1582年以降)に対応したツェラーの公式を使っています。
int day_of_week(int year, int month, int day)
引数:西暦 year、月 month 、日 day
戻り値:日曜部なら 0、月曜日なら 1、$\dots$、土曜日なら 6 を返す。
int day_of_week(int year, int month, int day)
{
int K, J;
if (month <= 2) {
month += 12;
--year;
}
K = year % 100;
J = year / 100;
return (day + (13 *(month + 1))/ 5 + K + K / 4 + J / 4 - 2 * J) % 7;
}
初出は、Project Euler 問題19 です。
次の順列を求める
与えられた順列の辞書順で次の順列を返します。2番目の引数は、C++ の next_permutation と異なり配列の個数を渡します。
int next_perm(int p[], int n)
引数:長さ n の順列 p を表す配列、関数呼び出し後、次の順列を格納する。
戻り値:次の順列がある場合 1、次の順列がない場合 0 を返す。
int next_perm(int p[], int n)
{
int i, j, t;
i = n - 2;
while ((i >= 0)&&(p[i] >= p[i + 1])) {
--i;
}
if (i == -1) {
return 0;
}
j = n - 1;
while (p[i] >= p[j]) {
--j;
}
t = p[i];
p[i] = p[j];
p[j] = t;
++i;
j = n - 1;
while (i < j) {
t = p[i];
p[i] = p[j];
p[j] = t;
++i;
--j;
}
return 1;
}
初出は、Project Euler 問題24 です。
後ろから読んだ数字を返す関数
後ろから読んだ数字を返す関数です。今後の Porject Euler で利用することがあるため紹介します。
int reversed_no(int number)
引数:number 自然数
戻り値:number を後ろから読んだ数字を返す。
int reversed_no(int number)
{
int reverse = 0;
while (number > 0) {
reverse = reverse * 10 + (number % 10);
number = number / 10;
}
return reverse;
}
初出は、Project Euler 問題4 です。
最後に
整数に関係する再利用できそうな関数は、前回にまとめて紹介しました。今回は、整数に関係しない再利用できない関数を紹介しました。
これからも、再利用できそうな関数は道具箱として紹介していきます。