On Tuesday, 10 January 2023 at 01:22:33 UTC, H. S. Teoh wrote:
Here's a challenge. Given an input year, for example, "2023", write a program that outputs (for the corresponding year):

Now, I wrote a nested class using range and copying from Matheus' code. Of course not as comprehensive as [your dcal](https://github.com/quickfur/dcal/blob/master/dcal.d). I like this one and even thought of a new challenge!

```d
void main()
{
  import std.stdio, std.string : cp = capitalize;
  import std.range, std.conv : to;

  with(new MyCalendar(2023, 12))
  {
    const title = dowToStr!2;
    foreach(month; range.take(6))
    {
      const mName = date.month.to!string;
      year.write(" ");           // current year
      mName.cp.writefln!"%s:";   // name of the month
      title.writefln!"%-(%s %)"; // days of week
      month.writeln;             // formatted days
    }
  }

class MyCalendar
{
  import std.array, std.datetime, std.conv : to;
  import std.string : capitalize;

  Range range;
  Date date;
  int year, month;

  this(int year, int month)
  {
    this.month = month;
    this.year = year;
    this.date = Date(year, month, 1);
    this.range = new Range();
  }

  class Range
  {
    enum empty = false;

    string front()
    {
      import std.format : fw = formattedWrite;
      auto res = appender!string;
      int day, dow = date.dayOfWeek;
      res.fw("%s", replicated(dow * 3)); // skip days

      for(day = 1; day <= date.daysInMonth; ++day)
      {
        if(++dow % 7) res.fw("%2s ", day);
        else res.fw("%2s\n", day);
      }
      if(dow % 7) res.put("\n");
      return res.data;
    }

    void popFront()
    {
      month++;
      if(month > 12)
      {
        ++year;
        month = 1;
      }
      date = Date(year, month, 1);
    }
  }

  auto dowToStr(size_t len = 0)()
  {
    alias E = DayOfWeek;
    string[] result;
    for(E x = E.min; x <= E.max; x++)
    {
      result ~= len ? x.to!string[0..len]
                    : x.to!string;
    }
    return result;
  }
}
```

SDB@79

Reply via email to