euler_ex/solutions/19/solution.livemd
2025-03-01 22:14:30 -05:00

68 lines
1.4 KiB
Markdown

# 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()
```