馬世勝 王德貴
公元紀(jì)年對稱日問題,也稱為世界完全對稱日。比如2021年12月2日,寫成20211202,大家一眼就看出,這個數(shù)字是左右對稱的,那么從公元紀(jì)年開始,到現(xiàn)在一共有多少個對稱日呢?
今天我們就用Python來探討一下公元紀(jì)年的對稱問題。
我們習(xí)慣的日期格式是XXXX年X月X日,當(dāng)然也可以用“.”代表年月。不過這種寫法日期的位數(shù)不一致,可以用零來補位,這樣年用4位數(shù)字,月和日用兩位數(shù)字,加一起為8位數(shù)字。如:2021年12月2日,寫成20211202。
在數(shù)學(xué)上,對稱有兩個含義:軸對稱和中心對稱。
軸對稱,即是沿著某條直線,翻折180度后,完全重合,這條直線也叫對稱軸,沿對稱軸翻折后兩側(cè)重合的點,叫對稱點。
中心對稱,即是沿著某一點旋轉(zhuǎn)180度,完全重合,這個點也叫對稱中心,繞對稱中心旋轉(zhuǎn)180度重合的點,叫對稱點。
日期數(shù)字是左右對稱的,我們叫對稱日,在數(shù)學(xué)上也叫回文數(shù)、回文日期,所以對稱日屬于軸對稱。
公元紀(jì)年從1開始,前面無需加0,所以開始紀(jì)年應(yīng)該是10101,年上正常按位計算,月和日都按兩位算,這樣就能開始計算從10101開始,到現(xiàn)在共有多少個對稱日了。
程序設(shè)計思想是先建立各月份的日期數(shù),并放在列表中,以備使用。
年、月、日三重循環(huán),最外層是年,然后是月,最里層是日。
年循環(huán),先判斷某年是不是閏年,如果是閏年,則2月份為29天,否則為28天。再就是輸入的年份,需要按照輸入的月份和日期終止循環(huán),如果不是輸入的年份,則正常按月份的日期循環(huán)。
月循環(huán),需要先知道是不是輸入的年月,如果是則循環(huán)到月即可,否則正常按日期列表循環(huán)。如果是小于10的,則前面加0補位。
日循環(huán),要判斷是不是輸入的日期,如果是輸入的日期,則按日期終止循環(huán),否則按日期列表循環(huán)。如果是小于10的,則前面加0補位。
當(dāng)輸入的日期,與循環(huán)日期相同時,不再繼續(xù)循環(huán),即循環(huán)到輸入的當(dāng)天。
將年月日轉(zhuǎn)換為字符串,添加到列表中,然后將列表反序,再判斷反序的列表和原列表是否相等,如果相等則添加到對稱日列表中,以備查詢和統(tǒng)計。
輸出對稱日列表的長度,也就是我們要求的值。也可以輸出列表中的數(shù)據(jù),即對稱日,也可以做日期切片來顯示多個數(shù)據(jù)。
自定義函數(shù),來判斷閏年。
年份循環(huán)中,判斷是否為閏年,如為閏年則返回1,否則返回0,如果為1則2月份的天數(shù)為29,否則為28天。
年月日循環(huán),以檢查每天的日期是否為對稱日。
輸出對稱日長度,即為從紀(jì)年開始,到輸入的日期中,有多少個對稱日,然后輸出最后一個對稱日期,如果想輸出全部日期,則修改程序即可。
在調(diào)試程序時,發(fā)現(xiàn)用列表反序,非常方便判斷,可以不用管多少位數(shù)字,只是循環(huán)的時間復(fù)雜度會增大。比如2021年12月2日,是第513個對稱日,顯示最后10個對稱日,如下圖。
公元9999年12月31日前的對稱日數(shù)目是796個,最后一個對稱日是9290年9月29日。
20000年12月31日前的對稱日數(shù)目是1226個,最后一個對稱日是13809年8月31日。
這兩個日期好像有點久遠(yuǎn)。但我們探討的過程中,體會了其中的樂趣,Python程序簡捷明了,易于理解。21世紀(jì)共有11個對稱日,剛剛過了20211202之后,下一個就是2030年3月2日。
大家若有興趣,可以用C語言和圖形化來編程,這里我就不再敘述了。