问题:将Haab历法转换为Tzolkin历法
输入:第一行,需要转换历法的个数(n),接下来的n行,每行输入一个haab历法。
输出:第一行,输出转换历法的个数,接下来的n行,每行输出一个Tzolkin历法。
解决:
将haab历法计算出来总天数days,再将days按照Tzolkin历法的表示方式表示出来。
1)将haab历法 day. month year转换为总天数days
day: 前18个月,每个月20天,0-19表示。最后一个月5天,用0-4表示。
year:第一年用0表示。
days = year * 365 + month之前所有月的总天数 + day + 1 ;
解释一下这里为什么加1; 因为Tzolkin历法的天数是用1-13表示的。也就是haab历法的0. pop 0表示第一年的第一天。 不加一的时候days = 0. 而实际Tzolkin的第一天用1表示。也就是haab历法的表示法的总天数与Tzolkin表示法的总天数差1。
2)将days总天数转换为Tzolkin历法表示法 days month year。第一年从0计数
year = ( days - 1 ) / 260
这里为什么减1,因为Tzolkin一年是260天,而第260天还是第一年。
days = ( days - 1 ) % 260 + 1
这里是计算不满一年的天数,那这里为什么减1,又加1?还是那个原因,因为260 % 260 == 0,但是实际是当年的第260天,所以这里需要减1,因为减1了,所以给人家加回来。
day = ( days - 1 ) % 13 + 1
month = (days - 1 )% 20 + 1
都是一样的道理。
3)剩下的解决部分是月份是字符串,如何映射到数值。
我这里采用的hash表,而且我自己用一种方法检测出来无冲突的一种映射。这块根据个人的。
代码:
#include <stdio.h>
#include <string.h>
#define HAAB 365
#define TZOLKIN 260
int a[] = {31, 23, 27, 17, 50, 21, 46, 38, 74, 28, 48, 62, 61, 84, 55, 37, 76, 64, 58} ;
int b[] = { 0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, 360} ;
int monthDays[100] ;
char kinMon[][10] = {"imix", "ik", "akbal", "kan", "chicchan", "cimi", "manik", "lamat", "muluk", "ok", "chuen", "eb", "ben", "ix", "mem", "cib", "caban", "eznab", "canac", "ahau"} ;
int main(int argc, char const *argv[])
{
int day ;
char month[7] ;
int year ;
int n ;
int days ;
int sum ;
int j = 0 ;
FILE* fp = fopen( "in.txt", "r" ) ;
for (int i = 0; i < (int)(sizeof(a)/sizeof(int)); ++i)
{
monthDays[ a[i] ] = b[ i ] ;
}
// fscanf( fp, "%d", &n ) ;
scanf( "%d", &n ) ;
printf("%d\n", n);
while( n-- )
{
// fscanf( fp, "%d. %s %d", &day, month, &year ) ;
scanf( "%d. %s %d", &day, month, &year ) ;
sum = 0 ;
j = strlen( month ) > 5 ? 5 : strlen(month) ;
for (int i = 0; i < j; ++i)
{
sum += 'z' - month[ i ] ;
}
days = year * HAAB + monthDays[ sum ] + day + 1 ;
// printf("haab day = %d\n", days);
year = ( days - 1 ) / TZOLKIN ;
days = ( days - 1 ) % TZOLKIN + 1 ;
j = ( days - 1 ) % 20 ;
day = ( days - 1 ) % 13 + 1 ;
printf("%d %s %d\n", day, kinMon[j], year);
}
return 0;}