問(wèn)題
百雞問(wèn)題來(lái)自《張邱建算經(jīng)》,原文:今有雞翁一直錢(qián)五,雞母一直前三,雞雛三直錢(qián)一,凡百錢(qián)買(mǎi)百雞。問(wèn):雞翁、母、雛各幾何?
這個(gè)問(wèn)題有三個(gè)未知數(shù),但卻只能列兩個(gè)方程。屬于不確定方程問(wèn)題。如果直接推算比較復(fù)雜,可以參考“百雞問(wèn)題”史話,而用編程實(shí)現(xiàn)比較直接。
命令式編程
用命令式編程有兩種解法,下面是Python程序
方法一:多重循環(huán)
for x in range(0, 21):
for y in range(0, 34):
z = 100 - x - y
if x * 5 + y * 3 + z / 3 == 100:
print(x, y, z)
方法二:列表演算
思路同方法一,Python 等編程語(yǔ)言支持列表演算,可以用一行代碼寫(xiě)完
[print(x, y, 100 - x - y) for x in range(21) for y in range(34) if x*5+y*3+(100-x-y)/3 == 100]
方法三:?jiǎn)窝h(huán)加邏輯推理
只循環(huán)公雞,剩下的錢(qián)買(mǎi)小雞,雞的總量超過(guò)100的,每超過(guò)8只就把9只小雞換成1只母雞,這樣總量就是100。
for x in range(21):
z = (20 - x) * 15
y = (x + z - 100) // 8
if (x + z - 100) % 8 == 0 and (x + z >= 100):
print(x, y, 100-x-y)
函數(shù)式編程
函數(shù)式編程語(yǔ)言沒(méi)有for/while循環(huán)語(yǔ)句,可以通過(guò)遞歸實(shí)現(xiàn),下面是Scheme代碼:
(define (chicken)
(chicken-iter 0 0))
(define (chicken-iter a b)
(cond [(eq? 100 (+ (* a 5) (* b 3) (/ (- 100 a b) 3)))
(printf "~s ~s ~s\n" a b (- 100 a b))])
(cond [(and (eq? a (truncate 100/5)) (eq? b (truncate 100/3)))
(display "")]
[else (if (eq? b (truncate 100/3))
(chicken-iter (+ a 1) 0)
(chicken-iter a (+ b 1)))]))
(chicken)
而Haskell支持列表演算,代碼可以很簡(jiǎn)短:
[(x, y, 100-x-y) | x <- [0..20], y<-[0..33], x*5+y*3+(100-x-y) `div` 3 == 100, (100-x-y) `mod` 3==0]
即使你不了解Haskell,代碼也不難理解。第三種方法的函數(shù)式編程感興趣讀者可以自行完成。