Calendar Contest Problem 6 — Ming Dynasty

View as PDF

Points: 25
Time limit: 1.0s
Memory limit: 128M

Author:
Problem type

After creating a calendar to Maximilien Robespierre's satisfaction and narrowly avoiding the guillotine, you were transported elsewhere and elsewhen. (Or maybe you were narrowly teleported just before the guillotine fell, in which case you deserve what's coming.)

Somehow, you ended up in the Forbidden City in what appeared to be Ming dynasty, and were brought before the Emperor, who was engrossed in a debate on calendar reform with his ministers. So far, the Ming Dynasty's official calendar is based on the principle of 平气, dividing the year into 24 periods of equal lengths, and making the start of each period solar terms. However, debate has been raging about switching to 定气, which determines the solar terms by ecliptic longitude. 定气 makes the solar terms reflect the true orbital motion of the Earth more, but creates the potential for two major solar terms (中气) to appear in a single month. You don't really understand the difference, but since 定气 is used in the 21st century, you inevitably lean towards that option. Since you are a programmer by trade, the Emperor decides to let you implement the proposed calendar, so he could see for himself how it would compare to the previous calendar. Failure, of course, is not an option, as that typically proves fatal during those times.

The proposed calendar is essentially identical to the modern Chinese lunar calendar. Every year consists of 12 months (or 13 in leap years). Each month may contain 29 or 30 days. The following convention is used to name dates:

• The first month of the year is called 正月. The other month names are the Chinese numerals + the character 月, i.e. 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月. For aesthetic reasons, the 11th month is called 冬月 and the last month of the year 腊月.
• For a leap month, the month is named as 闰 + the name of the preceding month. For example, if there is a leap month between 十月 and 冬月, it would be called 闰十月. The exception is if the leap year comes after the 12th month, in which case the leap month is 腊月 and the 12th month is called 十二月.
• The days of the month are named using a slightly modified form of Chinese numerals. If the Chinese numerals is a single character, e.g. 三, the character 初 is added as a prefix, i.e. 初三. If the Chinese numerals is two characters long, nothing is done, e.g. 正月十五. For days 21-29, the Chinese numerals would be three characters long, e.g. 二十一, which is undesirable, so we use the character 廿 to represent 20, i.e. 廿一. (Interesting fact: 廿 is essentially 十 with two vertical strokes, compare 卅 for 30 and 卌 for 40.)

It is important to note that in this version of the calendar, the dates are computed using the mean solar time at longitude 116°25' E, unlike the modern incarnation which uses the mean solar time at 120° E. Also note that the solar year is divided into 24 solar terms (二十四节气). The odd numbered terms are deemed minor (节气), and the even numbered ones are deemed major (中气). The two solstices and the two equinoxes are all considered major terms. The solar terms are named as follows, starting with the first term after the winter solstice: 小寒, 大寒, 立春, 雨水, 惊蛰, 春分, 清明, 谷雨, 立夏, 小满, 芒种, 夏至, 小暑, 大暑, 立秋, 处暑, 白露, 秋分, 寒露, 霜降, 立冬, 小雪, 大雪, 冬至.

The rules of the proposed calendar are simple. Every month begins on the date of the new moon. The date of the winter solstice (冬至) must be in the 11th month (冬月). The time period from the 11th month of a year (inclusive) until the 11th month of the next year (exclusive) is termed a 岁. In a normal 岁, there are 12 months. If there are 13, it's a leap 岁. The first month in the 岁 to not have a major solar term is deemed a leap month.

Fortunately, you have a copy of skyfield installed on your laptop, and along with a copy of JPL ephemerides DE440 and DE441, you could calculate the date of any solar term and new moon.

Interaction Protocol

This problem is interactive. Since you cannot use skyfield or download ephemerides on the judge, you must instead ask the grader to compute the dates of solar terms and new moons.

The first line of the input will consist of one integer, , the year to generate the calendar for. For your convenience, this will be given in the Gregorian calendar, and refers to the Chinese calendar year with the largest intersection with said Gregorian year.

During interaction with the grader, all times will be passed in UT1 in the ISO 8601 format, i.e. YYYY-mm-ddTHH:MM:SS. The year may have more than 4 digits, but its range is restricted to .

After receiving this line, your program can make the following queries:

• N <time>: this asks the grader for the time of the next new moon that happens at or after the specified time.
• S <time>: this asks the grader for the time of the next solar term that happens at or after the specified time.
• W <time>: this asks the grader for the time of the next winter solstice that happens at or after the specified time.

The grader will respond with the time followed by a new line character.

When your program is done generating the calendar, it should output DONE on its own line, and the calendar for that year. For every date in the year, you should output the date in Chinese, followed by a space. Then, you should output the corresponding Gregorian date in ISO 8601 format. If a solar term falls on this date, you should output the name of the solar term as well, preceded by a space. Your output should be encoded as UTF-8 with NFC normalization.

For your convenience, a list of dates of new moons, solar terms, and winter solstices are provided as plain text files. This should help you test your program locally.

Scoring

You will receive 75% of the points for this problem for generating the correct output.

The remaining points are awarded based on the number of queries made. For a perfect score, you must make at most 27 N queries, 30 S queries, and 3 W queries. For each query over the limit (up to 5), you are deducted 5% of the points for that test case. That is, if you make 5 or more queries over the limit, you will only receive 75% of the points for that test case.

Sample Interaction

>>> represents input from the interactor. The queries presented are only for reference purposes and may be neither necessary nor sufficient to solve the problem. Note that traditional characters are also accepted.

>>> 2021
W 2020-01-01T00:00:00
>>> 2020-12-21T10:02:20
S 2020-12-21T10:02:21
>>> 2021-01-05T03:23:26
N 2020-11-21T10:02:20
>>> 2020-12-14T16:16:35
DONE