Last active
January 11, 2025 04:36
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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