このページについて
このページは、paiza ラーニング内に開設されているコンテンツ「レベルアップ問題集」で取り扱われているプログラミング課題について、独自の見解を述べたものです。
見解については、paizaラーニングの規約に基づき、許可されている範囲でのみ公開していますが、その内容については paiza とは一切関係なく、また paiza の立場を反映したものではありませんのでご注意ください。
挑戦する課題
レベルアップ問題集の日付セットから「13日の金曜日(2桁) (paizaランク C 相当) 」を取り上げます。
以下は、問題公開 Web ページからの引用です。
問題
西暦年と月を無作為に選んだときに、その年月の13日が金曜日になる確率を求めてください。
ただし、各月の日数は以下のように決まることに注意してください。
- 4, 6, 9, 11月は30日
- 2月は閏年ならば29日、そうでなければ28日
- それ以外の月は31日
ただし、閏年は次のような年のことをいいます。
- 西暦が4で割り切れる年は閏年
- ただし、100で割り切れる年は平年
- ただし、400で割り切れる年は閏年
ただし、1800年1月1日は水曜日です。(現実のカレンダーです)
入力される値
なし
期待する出力
13日が金曜日になる確率を小数点以下2桁まで表示してください。
端数は切り捨ててください。
考え方
難しく考えてしまいそうだが、実はそれほど難しくはない。
与えられた年月日から曜日を求める「ツェラーの公式」を知っていれば簡単に求まる。
閏年のパターンは400年で一周するので、たとえば1800年を基準とすれば、2199年までの間に 13 日の金曜日が何回出現するのか、また母数を 400 * 12月としたとき何割(パーセントではない)となるのか求めれば良い。
解答例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// String(format:) を使うために必要 import Foundation // 曜日を求める func dayOfWeek(_ y: Int, _ m: Int, _ d: Int) -> Int { var y = y, m = m if 1...2 ~= m { y -= 1 m += 12 } return ( y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + d ) % 7 } // 13日の金曜日の出現回数 var count = 0.0 // 400年間計算できれば、範囲は限定されない for y in 1800..<2200 { for m in 1...12 { if dayOfWeek(y, m, 13) == 5 { // 毎年各月の13日が金曜(5)のとき count += 1 } } } print(String(format: "%.2f", count / (400.0 * 12.0))) |