# Project Euler Problem 19 ```elixir defmodule CountingSundays do defguard is_leap_year(y) when rem(y, 4) == 0 and (rem(y, 100) != 0 or rem(y, 400) == 0) @days %{ 0 => :sun, 1 => :mon, 2 => :tue, 3 => :wed, 4 => :thur, 5 => :fri, 6 => :sat, } @months %{ 0 => :jan, 1 => :feb, 2 => :mar, 3 => :apr, 4 => :may, 5 => :jun, 6 => :jul, 7 => :aug, 8 => :sep, 9 => :oct, 10 => :nov, 11 => :dec } def days_in_month(year, month) do case month do m when m in [:apr, :jun, :nov, :sep] -> 30 :feb when is_leap_year(year) -> 29 :feb -> 28 _ -> 31 end end def add_days(d, days), do: rem(d + days, 7) defp count_sundays_between(year, month, fin_year, fin_month, _, acc) when fin_month < month and fin_year == year or year > fin_year do acc end defp count_sundays_between(year, month, fin_year, fin_month, d, acc) do next = add_days(d, days_in_month(year, @months[month])) acc = if @days[next] == :sun, do: acc + 1, else: acc {year, month} = case month do 11 -> { year + 1, 0} n -> { year, n + 1} end count_sundays_between(year, month, fin_year, fin_month, next, acc) end def count_sundays() do count_sundays_between(1900, 0, 2000, 11, 1, 0) - count_sundays_between(1900, 0, 1900, 11, 1, 0) end end ``` ```elixir CountingSundays.count_sundays() ```