Calendar Contest Problem 6 — Ming Dynasty

View as PDF

Submit solution

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, y (1600 < y < 17\,150), 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 [1600, 17\,151].

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
正月初一 2021-02-12
正月初二 2021-02-13
正月初三 2021-02-14
正月初四 2021-02-15
正月初五 2021-02-16
正月初六 2021-02-17
正月初七 2021-02-18 雨水
正月初八 2021-02-19
正月初九 2021-02-20
正月初十 2021-02-21
正月十一 2021-02-22
正月十二 2021-02-23
正月十三 2021-02-24
正月十四 2021-02-25
正月十五 2021-02-26
正月十六 2021-02-27
正月十七 2021-02-28
正月十八 2021-03-01
正月十九 2021-03-02
正月二十 2021-03-03
正月廿一 2021-03-04
正月廿二 2021-03-05 惊蛰
正月廿三 2021-03-06
正月廿四 2021-03-07
正月廿五 2021-03-08
正月廿六 2021-03-09
正月廿七 2021-03-10
正月廿八 2021-03-11
正月廿九 2021-03-12
二月初一 2021-03-13
二月初二 2021-03-14
二月初三 2021-03-15
二月初四 2021-03-16
二月初五 2021-03-17
二月初六 2021-03-18
二月初七 2021-03-19
二月初八 2021-03-20 春分
二月初九 2021-03-21
二月初十 2021-03-22
二月十一 2021-03-23
二月十二 2021-03-24
二月十三 2021-03-25
二月十四 2021-03-26
二月十五 2021-03-27
二月十六 2021-03-28
二月十七 2021-03-29
二月十八 2021-03-30
二月十九 2021-03-31
二月二十 2021-04-01
二月廿一 2021-04-02
二月廿二 2021-04-03
二月廿三 2021-04-04 清明
二月廿四 2021-04-05
二月廿五 2021-04-06
二月廿六 2021-04-07
二月廿七 2021-04-08
二月廿八 2021-04-09
二月廿九 2021-04-10
二月三十 2021-04-11
三月初一 2021-04-12
三月初二 2021-04-13
三月初三 2021-04-14
三月初四 2021-04-15
三月初五 2021-04-16
三月初六 2021-04-17
三月初七 2021-04-18
三月初八 2021-04-19
三月初九 2021-04-20 谷雨
三月初十 2021-04-21
三月十一 2021-04-22
三月十二 2021-04-23
三月十三 2021-04-24
三月十四 2021-04-25
三月十五 2021-04-26
三月十六 2021-04-27
三月十七 2021-04-28
三月十八 2021-04-29
三月十九 2021-04-30
三月二十 2021-05-01
三月廿一 2021-05-02
三月廿二 2021-05-03
三月廿三 2021-05-04
三月廿四 2021-05-05 立夏
三月廿五 2021-05-06
三月廿六 2021-05-07
三月廿七 2021-05-08
三月廿八 2021-05-09
三月廿九 2021-05-10
三月三十 2021-05-11
四月初一 2021-05-12
四月初二 2021-05-13
四月初三 2021-05-14
四月初四 2021-05-15
四月初五 2021-05-16
四月初六 2021-05-17
四月初七 2021-05-18
四月初八 2021-05-19
四月初九 2021-05-20
四月初十 2021-05-21 小满
四月十一 2021-05-22
四月十二 2021-05-23
四月十三 2021-05-24
四月十四 2021-05-25
四月十五 2021-05-26
四月十六 2021-05-27
四月十七 2021-05-28
四月十八 2021-05-29
四月十九 2021-05-30
四月二十 2021-05-31
四月廿一 2021-06-01
四月廿二 2021-06-02
四月廿三 2021-06-03
四月廿四 2021-06-04
四月廿五 2021-06-05 芒种
四月廿六 2021-06-06
四月廿七 2021-06-07
四月廿八 2021-06-08
四月廿九 2021-06-09
五月初一 2021-06-10
五月初二 2021-06-11
五月初三 2021-06-12
五月初四 2021-06-13
五月初五 2021-06-14
五月初六 2021-06-15
五月初七 2021-06-16
五月初八 2021-06-17
五月初九 2021-06-18
五月初十 2021-06-19
五月十一 2021-06-20
五月十二 2021-06-21 夏至
五月十三 2021-06-22
五月十四 2021-06-23
五月十五 2021-06-24
五月十六 2021-06-25
五月十七 2021-06-26
五月十八 2021-06-27
五月十九 2021-06-28
五月二十 2021-06-29
五月廿一 2021-06-30
五月廿二 2021-07-01
五月廿三 2021-07-02
五月廿四 2021-07-03
五月廿五 2021-07-04
五月廿六 2021-07-05
五月廿七 2021-07-06
五月廿八 2021-07-07 小暑
五月廿九 2021-07-08
五月三十 2021-07-09
六月初一 2021-07-10
六月初二 2021-07-11
六月初三 2021-07-12
六月初四 2021-07-13
六月初五 2021-07-14
六月初六 2021-07-15
六月初七 2021-07-16
六月初八 2021-07-17
六月初九 2021-07-18
六月初十 2021-07-19
六月十一 2021-07-20
六月十二 2021-07-21
六月十三 2021-07-22 大暑
六月十四 2021-07-23
六月十五 2021-07-24
六月十六 2021-07-25
六月十七 2021-07-26
六月十八 2021-07-27
六月十九 2021-07-28
六月二十 2021-07-29
六月廿一 2021-07-30
六月廿二 2021-07-31
六月廿三 2021-08-01
六月廿四 2021-08-02
六月廿五 2021-08-03
六月廿六 2021-08-04
六月廿七 2021-08-05
六月廿八 2021-08-06
六月廿九 2021-08-07 立秋
七月初一 2021-08-08
七月初二 2021-08-09
七月初三 2021-08-10
七月初四 2021-08-11
七月初五 2021-08-12
七月初六 2021-08-13
七月初七 2021-08-14
七月初八 2021-08-15
七月初九 2021-08-16
七月初十 2021-08-17
七月十一 2021-08-18
七月十二 2021-08-19
七月十三 2021-08-20
七月十四 2021-08-21
七月十五 2021-08-22
七月十六 2021-08-23 处暑
七月十七 2021-08-24
七月十八 2021-08-25
七月十九 2021-08-26
七月二十 2021-08-27
七月廿一 2021-08-28
七月廿二 2021-08-29
七月廿三 2021-08-30
七月廿四 2021-08-31
七月廿五 2021-09-01
七月廿六 2021-09-02
七月廿七 2021-09-03
七月廿八 2021-09-04
七月廿九 2021-09-05
七月三十 2021-09-06
八月初一 2021-09-07 白露
八月初二 2021-09-08
八月初三 2021-09-09
八月初四 2021-09-10
八月初五 2021-09-11
八月初六 2021-09-12
八月初七 2021-09-13
八月初八 2021-09-14
八月初九 2021-09-15
八月初十 2021-09-16
八月十一 2021-09-17
八月十二 2021-09-18
八月十三 2021-09-19
八月十四 2021-09-20
八月十五 2021-09-21
八月十六 2021-09-22
八月十七 2021-09-23 秋分
八月十八 2021-09-24
八月十九 2021-09-25
八月二十 2021-09-26
八月廿一 2021-09-27
八月廿二 2021-09-28
八月廿三 2021-09-29
八月廿四 2021-09-30
八月廿五 2021-10-01
八月廿六 2021-10-02
八月廿七 2021-10-03
八月廿八 2021-10-04
八月廿九 2021-10-05
九月初一 2021-10-06
九月初二 2021-10-07
九月初三 2021-10-08 寒露
九月初四 2021-10-09
九月初五 2021-10-10
九月初六 2021-10-11
九月初七 2021-10-12
九月初八 2021-10-13
九月初九 2021-10-14
九月初十 2021-10-15
九月十一 2021-10-16
九月十二 2021-10-17
九月十三 2021-10-18
九月十四 2021-10-19
九月十五 2021-10-20
九月十六 2021-10-21
九月十七 2021-10-22
九月十八 2021-10-23 霜降
九月十九 2021-10-24
九月二十 2021-10-25
九月廿一 2021-10-26
九月廿二 2021-10-27
九月廿三 2021-10-28
九月廿四 2021-10-29
九月廿五 2021-10-30
九月廿六 2021-10-31
九月廿七 2021-11-01
九月廿八 2021-11-02
九月廿九 2021-11-03
九月三十 2021-11-04
十月初一 2021-11-05
十月初二 2021-11-06
十月初三 2021-11-07 立冬
十月初四 2021-11-08
十月初五 2021-11-09
十月初六 2021-11-10
十月初七 2021-11-11
十月初八 2021-11-12
十月初九 2021-11-13
十月初十 2021-11-14
十月十一 2021-11-15
十月十二 2021-11-16
十月十三 2021-11-17
十月十四 2021-11-18
十月十五 2021-11-19
十月十六 2021-11-20
十月十七 2021-11-21
十月十八 2021-11-22 小雪
十月十九 2021-11-23
十月二十 2021-11-24
十月廿一 2021-11-25
十月廿二 2021-11-26
十月廿三 2021-11-27
十月廿四 2021-11-28
十月廿五 2021-11-29
十月廿六 2021-11-30
十月廿七 2021-12-01
十月廿八 2021-12-02
十月廿九 2021-12-03
冬月初一 2021-12-04
冬月初二 2021-12-05
冬月初三 2021-12-06
冬月初四 2021-12-07 大雪
冬月初五 2021-12-08
冬月初六 2021-12-09
冬月初七 2021-12-10
冬月初八 2021-12-11
冬月初九 2021-12-12
冬月初十 2021-12-13
冬月十一 2021-12-14
冬月十二 2021-12-15
冬月十三 2021-12-16
冬月十四 2021-12-17
冬月十五 2021-12-18
冬月十六 2021-12-19
冬月十七 2021-12-20
冬月十八 2021-12-21 冬至
冬月十九 2021-12-22
冬月二十 2021-12-23
冬月廿一 2021-12-24
冬月廿二 2021-12-25
冬月廿三 2021-12-26
冬月廿四 2021-12-27
冬月廿五 2021-12-28
冬月廿六 2021-12-29
冬月廿七 2021-12-30
冬月廿八 2021-12-31
冬月廿九 2022-01-01
冬月三十 2022-01-02
腊月初一 2022-01-03
腊月初二 2022-01-04
腊月初三 2022-01-05 小寒
腊月初四 2022-01-06
腊月初五 2022-01-07
腊月初六 2022-01-08
腊月初七 2022-01-09
腊月初八 2022-01-10
腊月初九 2022-01-11
腊月初十 2022-01-12
腊月十一 2022-01-13
腊月十二 2022-01-14
腊月十三 2022-01-15
腊月十四 2022-01-16
腊月十五 2022-01-17
腊月十六 2022-01-18
腊月十七 2022-01-19
腊月十八 2022-01-20 大寒
腊月十九 2022-01-21
腊月二十 2022-01-22
腊月廿一 2022-01-23
腊月廿二 2022-01-24
腊月廿三 2022-01-25
腊月廿四 2022-01-26
腊月廿五 2022-01-27
腊月廿六 2022-01-28
腊月廿七 2022-01-29
腊月廿八 2022-01-30
腊月廿九 2022-01-31

Comments

There are no comments at the moment.