こんにちは、ひらのです。
2024年の2月は「閏年」ですね。
閏年だからといって何か特別なことがあるわけではないのですが…
閏年と言えば、プログラミング入門でお馴染みのアレです。
「特定の年が閏年かそうでないかを判定するプログラムを作成しなさい」
というよく聞くアレ。
今回は私もウン十年ぶりに初心に戻って…閏年判定プログラムについて考えてみようと思います。
そもそも閏年とは…
閏年(leap year、intercalary year)とは…
Wikipediaより引用
閏(1年の月数や日数が普段の年よりも多いこと)のある年である。
これに対し、閏年ではない年を平年(common year)と呼ぶ。
24時間365日でカウントしてるとちょっとズレていくので閏を設けて時差を合わせましょう。ってことですね。
この長い時間かけてズレてい行く問題を解決するために昔の頭の良い人達が色々と考えて…
グレゴリオ暦を作成し、その中で閏年の条件を設けました。
グレゴリオ暦では次の規則に従って閏年を設けます。
この条件に沿って考えれば100年後、1000年後の閏年がいつなのか ということも確認できる というわけです。
昔々、プログラミングのプの字も理解していなかった私は当時の先生に
「特定の年が閏年かそうでないかを判定するプログラムを作成しなさい」と言われ…
(閏年判定プログラムなんていらなくね…?)とか思ってました。
閏年の判定条件は絶妙な複雑さで、プログラミングの「条件分岐」の練習に良い題材なんだろうなとか思います。
なので、Hello worldの次くらいに誰もが通る道かもしれません。
さて、ここからプログラミング的に閏年判定について考えていきます。
先ほどの閏年の条件を使ってフローチャートを書いてみます。
このように条件1つずつに対して「YESかNOか」の判定を行い、与えられた西暦年が閏年かどうかを振り分けて判定を行います。
プログラミングではこのような「〇〇だったらAの結果、××だったらBの結果へ」という条件分岐の処理はよく使いますが、この概念の流れを知るのに閏年の判定は分かりやすい題材です。
フローチャートを書いて、条件での分岐方法が明確になったので
if文を使ってJavascriptで実際にプログラムを書いてみます。
const year = 2024;
if(year % 400 === 0) {
//西暦年が400で割り切れる
console.log('閏年')
} else {
//西暦年が400で割り切れない
if(year % 100 === 0) {
//100で割り切れる
console.log('平年')
} else {
//100で割り切れない
if(year % 4 === 0) {
//4で割り切れる
console.log('閏年')
} else {
//4で割り切れない
console.log('平年')
}
}
}
すなおに条件を追って書いていくとこのようになります。
この方法で条件分岐はできていますが、プログラムコードが少し読みにくいです…
if文の中にif文を書く(入れ子)の書き方はコードの可読性が下がってしまうため
良くないと言われることが多いです…
また、条件が複雑になればなるほどif文の入れ子が深くなり可読性もどんどんと下がっていきます。
なのでこのコードをもう少しわかりやすい形に直してみます。
const year = 2024;
if(year % 400 === 0) {
//西暦年が400で割り切れる
console.log('閏年')
} else if(year % 100 === 0) {
//西暦年が400で割り切れず、100で割り切れる
console.log('平年')
} else if(year % 4 === 0) {
//西暦年が400で割り切れず、100で割り切れず、4で割り切れる
console.log('閏年')
} else {
//西暦年が400で割り切れず、100で割り切れず、4で割り切れない
console.log('平年')
}
else if
を使って条件分岐を行い、最後は「どの条件も満たさない場合は平年」という記述に変更しました。
入れ子の記述がなくなり、少しすっきりしました。
さらにコードを読みやすくしていきます。
const year = 2024;
if(year % 400 === 0 || year % 100 !== 0 && year % 4 === 0) {
//西暦年が400で割り切れる か 西暦年が100で割り切れず かつ 4で割り切れる
console.log('閏年')
} else {
//上記の条件以外の場合
console.log('平年')
}
if の()中の条件の記述が少し複雑になりましたが、全体のコードは短くなり可読性がかなり良くなりました。
このifの条件の中で「○○かつ(AND)△△」「××か(OR)□□」という書き方が登場します。
この書き方を最初に学ぶものも閏年判定だったような気がします。
実際にJavaScriptでグレゴリオ暦が始まってから今年までの442年間で何回閏年があったかを調べてみました。
See the Pen Untitled by hirano (@_y_hirano) on CodePen.
数百年の中から閏年の条件に一致する年を手作業で調べるのは途方もない作業ですが
プログラムで条件を判断させれば一瞬で調べることができました。
このような処理はカレンダー機能のあるアプリ制作等では利用する機会もありそうですね。
ウン十年ぶりに閏年の判定について考えてみました。
作成するプログラムにもよりますが、実務で閏年判定を行う機会は殆どありませんでしたが
学生の時に先生に教えられながら作った閏年判定のおかげでif文の使い方を理解できたのも体感として覚えています。
今回たまたま閏年でブログのネタにしてみましたが久々に思い出してみると面白かったです。
次回の閏年は2028年。それまでに新しい閏年ネタを考えてみようと思います。