'yyyy년 dd월 n번째 x요일'과 같은 식으로 날짜가 주어졌을 때 정확한 날짜를 계산하는 문제였다. 'n번째'로 정확히 지정되는 경우도 있지만, '마지막 주'나 'teen번째'(이 문제에서만 쓰이는 용어로, 날짜를 영어로 썼을 때 teen으로 끝나는 13~19일 중 하루를 가리킨다)도 있어 아주 약간 더 복잡해졌다.
기본적으로 리스트를 대상으로 호출하는 Enum.at/2
은 금기로 생각하고 있지만, 이 문제의 경우 리스트의 항목 수가 많아 봐야 대여섯 개 정도여서 부담을 조금 내려놓고 마음껏 호출했다.
defmodule Meetup do
@moduledoc """
Calculate meetup dates.
"""
@type weekday ::
:monday
| :tuesday
| :wednesday
| :thursday
| :friday
| :saturday
| :sunday
@type schedule :: :first | :second | :third | :fourth | :last | :teenth
@weekday_mapping %{
monday: 1,
tuesday: 2,
wednesday: 3,
thursday: 4,
friday: 5,
saturday: 6,
sunday: 7
}
@doc """
Calculate a meetup date.
The schedule is in which week (1..4, last or "teenth") the meetup date should
fall.
"""
@spec meetup(pos_integer, pos_integer, weekday, schedule) :: Date.t()
def meetup(year, month, weekday, schedule) do
first_day = Date.new!(year, month, 1)
last_day = Date.end_of_month(first_day)
weekday_code = @weekday_mapping[weekday]
Date.range(first_day, last_day)
|> Enum.filter(fn d ->
Date.day_of_week(d) == weekday_code
end)
|> then(fn dates ->
case schedule do
:first -> hd(dates)
:second -> Enum.at(dates, 1)
:third -> Enum.at(dates, 2)
:fourth -> Enum.at(dates, 3)
:last -> List.last(dates)
:teenth -> Enum.find(dates, fn d -> d.day in 13..19 end)
end
end)
end
end
'호두나무 공방 > Exercism in Elixir' 카테고리의 다른 글
Need For Speed - Exercism in Elixir (0) | 2022.09.07 |
---|---|
Luhn - Exercism in Elixir (0) | 2022.09.06 |
Complex Numbers - Exercism in Elixir (0) | 2022.08.19 |
Square Root - Exercism in Elixir (0) | 2022.08.18 |
Pythagorean Triplet - Exercism in Elixir (0) | 2022.08.17 |