ScalaでProject Euler(36)

Problem 19

iterate

Iterator.iterate(x)(f)

とすると、

x, f(x), f(f(x)), ...

という列が生成されます。(曜日, 年, 月)というタプルを次の月のタプルにする関数fとすれば簡単に曜日の列が生成できます。

val wdays = List(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

def is_leap(y :Int) =
    if(y % 4 != 0)
        false
    else if(y % 100 != 0)
        true
    else
        y % 400 == 0

def next_weekday(s :(Int,Int,Int)) = s match {
    case (w, y, 2) if is_leap(y) => ((w + 29) % 7, y, 3)
    case (w, y, 12) => ((w + 31) % 7, y + 1, 1)
    case (w, y, m) => ((w + wdays(m-1)) % 7, y, m + 1)
}

val it = Iterator.iterate((1, 1900, 1))(next_weekday)
val it2 = it.filter(x => x._2 > 1900).takeWhile(x => x._2 < 2001)
println (it2.filter(x => x._1 == 0).size)