Skip to content

Instantly share code, notes, and snippets.

@stanleytangerror
Last active January 11, 2025 04:36
Show Gist options
  • Select an option

  • Save stanleytangerror/fa65df941cd6ebf4769d5f4b1e3e1e12 to your computer and use it in GitHub Desktop.

Select an option

Save stanleytangerror/fa65df941cd6ebf4769d5f4b1e3e1e12 to your computer and use it in GitHub Desktop.
Inspired by [CppCon 2015: Eric Niebler "Ranges for the Standard Library"](https://www.youtube.com/watch?v=mFUXNMfaciE&ab_channel=CppCon)
// Inspired by CppCon 2015: Eric Niebler "Ranges for the Standard Library", https://www.youtube.com/watch?v=mFUXNMfaciE&ab_channel=CppCon
using System.Globalization;
public static class Program
{
static IEnumerable<IEnumerable<T>> Transpose<T>(this IEnumerable<IEnumerable<T>> source)
=> source
.SelectMany(inner => inner.Select((item, index) => new { item, index }))
.GroupBy(i => i.index, i => i.item)
.Select(g => g.AsEnumerable());
static string Join(this IEnumerable<string> source, string str) => string.Join(str, source);
static string FormatDay(this DateOnly day) => day.Day.ToString().PadLeft(3);
static string MonthTitle(this DateOnly day)
=> CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(day.Month).PadRight(16).PadLeft(21);
static IEnumerable<string> FormatWeeks(this IEnumerable<IEnumerable<DateOnly>> weeks)
=> weeks.Select(w =>
string.Concat(
new string(' ', (w.First().DayOfWeek - DayOfWeek.Sunday) * 3),
w.Select(d => d.FormatDay()).Join(string.Empty)
)
.PadRight(21)
);
static IEnumerable<DateOnly> DatesInYear(int year)
{
int daysInYear = DateTime.IsLeapYear(year) ? 366 : 365;
return Enumerable.Range(0, daysInYear).Select(offset => new DateOnly(year, 1, 1).AddDays(offset));
}
static IEnumerable<IEnumerable<DateOnly>> ByMonth(this IEnumerable<DateOnly> days)
=> days.GroupBy(d => (d.Year, d.Month), d => d);
static IEnumerable<IEnumerable<DateOnly>> ByWeek(this IEnumerable<DateOnly> month)
=> month.GroupBy(
d => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(d.ToDateTime(default), CalendarWeekRule.FirstDay, DayOfWeek.Sunday),
d => d);
static IEnumerable<IEnumerable<string>> LayoutMonths(this IEnumerable<IEnumerable<DateOnly>> months)
=> months
.Select(m =>
{
var weekCount = m.ByWeek().Count();
return Enumerable.Concat(
Enumerable.Concat(
[m.First().MonthTitle()],
m.ByWeek().FormatWeeks()
),
Enumerable.Repeat(new string(' ', 21), 7 - weekCount)
);
});
static IEnumerable<IEnumerable<IEnumerable<string>>> TransposeMonths(this IEnumerable<IEnumerable<IEnumerable<string>>> months)
=> months.Select(c => c.Transpose());
static IEnumerable<string> JoinMonths(this IEnumerable<IEnumerable<string>> months)
=> months.Select(c => c.Join(" |"));
public static void Main()
{
var monthsInLine = 4;
var r = DatesInYear(2025)
.ByMonth()
.LayoutMonths()
.Chunk(monthsInLine)
.TransposeMonths()
.SelectMany(m => m)
.JoinMonths();
foreach (var l in r)
Console.WriteLine(l);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment