牟曉東
“雞兔同籠”趣題最早記載于1500多年前的中國古代數學著作《孫子算經》中的“卷下”第31題(后傳至日本演變為“鶴龜算”),原題為:“今有雉兔同籠,上有三十五頭,下有九十四足,問雉兔各幾何?”意思是“雞和兔的總頭數是35,總腳數是94,雞和兔各有幾只?”。
1.問題求解
假設雞有x只,兔有y只,根據題意列方程為:
x+y=35,2x+4y=94。
求解,得:x=23,y=12;即雞有23只(46只腳)、兔有12只(48只腳)。
2.Python編程求解
如果使用Python語言來編寫程序的話,可使用for循環、range()函數和if條件判斷來完成。先使用“heads = 35”和“feet = 94”兩個賦值語句,保存雞和兔的總頭數和總腳數;接著使用range()函數進行for循環,讓雞的數目從1開始計數加1循環,循環體中的if條件為“2*x + 4*y == feet”,即“雞數目的兩倍加兔數目的四倍之和等于總腳數”,條件成立的話,使用print語句進行最終雞兔數目的輸出。保存程序為“雞兔同籠1.py”,運行結果顯示為“雞有 23 只,兔有 12 只。”(如圖1)。

3.升級版的“雞兔同籠”
考慮到“雞兔同籠”原題中所給出的總頭數和總腳數是固定的35和94,因此最終的求解也是固定的“23只雞、12只兔”。如果將題目進行“升級”,雞和兔的總頭數與總腳數均由用戶從鍵盤輸入,仍然來求雞和兔的數目,應該如何編寫程序代碼呢?
首先使用標準輸入函數input來接收用戶從鍵盤上輸入的信息,比如“heads = input('請輸入雞和兔的總頭數:')”和“feet = input('請輸入雞和兔的總腳數:')”。但在此需要特別注意的是,Python的input函數接收到的輸入數據是str字符串(雖然表面上看是數字),必須要使用int來轉換成整數型才能進行數學運算,語句為“heads = int(heads)”和“feet = int(feet)”。
接下來仍然是使用range()函數進行for循環:“for x in range(0,(heads+1))”。此時要充分考慮到用戶所輸入數據的計算結果,很有可能會出現“只有雞”或“只有兔”的情況。舉例:用戶輸入的總頭數是10、總腳數是20,運算結果就應該是“10只雞、0只兔”;或輸入總頭數是10、總腳數是40,運算結果則是“0只雞、10只兔”。因為在計算機編程語言中,數字0總是被看作是最起始的值,Python的列表、字符串和元組等的元素均是從0開始進行索引的。不管是“0只雞”還是“0只兔”,在計算機看來,這都是“雞兔同籠”,只不過數目是0而已。另外,由于range()函數的兩個參數是“左閉右開”型的區間,即第一個參數是被計算在內,而第二個參數卻是不包括在內的(只計算到它的前一個元素);所以,第二個參數應該設置為“heads+1”,這樣就能在循環時計算到它的前一個元素(即“heads”),也就是“0只兔”的情況(“x=0”則是“0只雞”)(如圖2)。

循環體與之前類似,仍然是if條件判斷“2*x + 4*y == feet”是否成立,成立的話則使用print輸出結果,然后使用break語句跳出循環。因為不確定用戶從鍵盤上輸入的兩個數據是否恰好為“有效解”——雞和兔的數目必須是整數只,所以在循環體外應該再添加一個“if 2*x + 4*y != feet”判斷語句,將這種無法進行整數結果計算的情況進行提示:“輸入的總頭數和總腳數不合法”。沒有該print語句的話,程序也能正常運行,但對于這種“意外”沒有任何提示,程序缺少必要的友好性(如圖3)。

最后將程序保存為“雞兔同籠2.py”,運行幾次進行測試,輸入的總頭數和總腳數包括原題目中的“35、94”、雞兔各為0只、“30、110”四種合法數值,程序均輸出了正確的計算結果;最后一個測試輸入“8、100”,結果就提示“輸入的總頭數和總腳數不合法”(如圖4)。
