python,计算并发现闰月的规律

a=29.53059  #一个月是这么多天
N=1000      #计算这么多个月的

#b是个N行3列的二维数组。
b=[[0,0,0] for i in range(N)]
#开始计算
b[0][0]=a
b[0][1]=29
b[0][2]=b[0][0]-b[0][1]
for i in range(1,N):
    b[i][0]=b[i-1][2]+a
    if b[i][0]>=30:
        b[i][1]=30
    else:
        b[i][1]=29
    b[i][2]=b[i][0]-b[i][1]

#生成大小月,连续两个大月,标记为闰月。
月份=[]
for i in range(N):
    if b[i][1]==29:
        月份.append('小')
    else:
        月份.append('大')
for i in range(1,N):
    if 月份[i]=='大' and 月份[i-1]=='大':
        月份[i]='闰'
#print(月份)

def print_b(b):
    for line in b:
        #print(line)
        print(f'{line[0]:.6f} {line[1]:2d} {line[2]:.6f}')
print_b(b)
print('-'*40)  #画一条分割线

串=''.join(月份)
#print(串)

#打印“串”,遇到“闰”就换行。
def print串(串):
    for ch in 串:
        if ch=='闰':
            print(ch)
        else:
            print(ch,end='')
print串(串)

import fractions
f=fractions.Fraction('0.53059')
print('-'*40)  #画一条分割线
print(f.limit_denominator(100))
print(f.limit_denominator(1000))

已知一个月是29.53059天,如果正好是29.5天/月,则规律很简单,一个小月(29天)和一个大月(30天)交替出现即可。但实际上情况要复杂一点,编写了如上程序,进行计算和模拟。

a是个常数。
b是个N行3列的二维表,A列表示浮点数的天数,B列表示这个月的整数天数,C列表示当月剩余天数。

模拟的结果和实际的农历不同。例如,模拟结果中,没有出现连续两个小月,而实际上农历包括这种情况。如2023-4-19和2023-5-18。

或许这是因为设计农历时,中国还是古代,数据没有现在这么精确,所以结果有差距。

以下分析python程序:
第5行,建立一个二维数组。虽然一行就出来了,但我认为不够简练。

第7到第9行,初始化二维数组的第一行。

第10到第16行,建立二维数组。

第19到第27行,由上述二维数组产生一维数组,即取出二维数组的第二列。当月天数为29天的是小月,为30天的是大月,连续两个大月,用闰月表示。

第30行,打印二维数组。

第37行,把标记着“小大闰”的月份,串成一串。

第41行,打印“串”,遇到“闰”就换行。

最后两行,计算浮点数的近似分数,denominator是分母的意思。

然后解释模拟结果的含义。有两种模式,对应于两个近似分数。一个是29.53059≈29+26/49,每49个月有26个大月,这26个大月的分布情况是:
小大小大小大小大小大小大小大小大闰,17个月
再17个月,再15个月,构成49个月。
17+17+15=49

另一种模式对应29+477/899,每899个月有477个大月,分布情况是:
17+(17+17+15)×18
先是17个月的“小大小大……闰”,
然后是(17+17+15),如模式一所述。
这一模式要重复18次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值