Rosetta Code has a number of programming tasks with example solutions in multiple languages. One of those tasks is find the last Sunday of each month. Here’s a sample in C#:
DateTime date;
for (int i = 1; i <= 12; i++)
{
date = new DateTime(year, i, DateTime.DaysInMonth(year, i), System.Globalization.CultureInfo.CurrentCulture.Calendar);
while (date.DayOfWeek != DayOfWeek.Sunday)
{
date = date.AddDays(-1);
}
Console.WriteLine(date.ToString("yyyy-MM-dd"));
}
I thought it might be fun to write an F# version, code golf style, that fits in a tweet:
The general gist of that solution was to create a list of all days in each month in reverse order and find the first Sunday (which will be the last):
[for month in 1..12->
[for day in System.DateTime.DaysInMonth(2014,month).. -1.. 1->
System.DateTime(2014,month,day).DayOfWeek,(month,day)]
|> Seq.find (fun (dayOfWeek,_) -> dayOfWeek = System.DayOfWeek.Sunday)
]
Enter Petricek
Then Tomas Petricek came up with a neat solution that had enough space left over to execute against @fsibot:
Tomas’s solution evaluates each day of the year, yielding the last Sundays as dates:
[for days in 0.0 .. 365.0 do
let day = System.DateTime(2014,1,1).AddDays(days) in
if int day.DayOfWeek = 0 && day.AddDays(7.).Month <> day.Month
then yield day
]
Wellum Reprise
Meanwhile Richard Wellum suggested an alternate solution in C#, which I was able to translate to standalone F# with space left over for a pretty print:
Richard's solution is to calculate the last day of the month, find the day of week and subtract that value to reach the Sunday. Here's a version with variable names:
[for month in 1..12->
let lastDay = System.DateTime(2014,month,1).AddMonths(1).AddDays(-1.) in
lastDay.AddDays(-(lastDay.DayOfWeek|>int|>float)).ToString("m")
]
Conclusion
Finding the last Sunday of each month in a tweet now appears to be a solved problem :)