def solve(numLegs, numHeads):
for numChicks in range(0, numHeads + 1):
numPigs = numHeads - numChicks
totLegs = 4*numPigs + 2*numChicks
if totLegs == numLegs:
return [numPigs, numChicks]
return [None, None]
def barnYard(heads, legs):
pigs, chickens = solve(legs, heads)
if pigs == None:
print "There is no solution."
else:
print 'Number of pigs: ', pigs
print 'Number of Chickens: ', chickens
我正在学习Python并且遇到了这个例子,有人可以用简单的英语(或伪代码)解释这是逐行的。
非常感谢
答案 0 :(得分:8)
solve
计算总数达到给定数量的头部和腿部所需的小鸡数(1头,2腿)和多少头猪(1头,4腿)。
它使用“蛮力”,即最简单的方法:
for
numChicks in range(0, numHeads +
1):
的作用,因为range
给出了整数
从包括的起始值
到结束值排除); numChicks
进行计算
那将会有多少只猪
请求的头数,由
声明numPigs = numHeads - numChicks
totLegs = 4*numPigs + 2*numChicks
totLegs
是否相等
请求的号码:如果是,则返回
包含两个项目的列表,数字
小鸡和猪解决问题for
循环
一个价值,它知道没有解决方案,
并表示通过返回列表
其中两项均为None
。 barnYard
只需将解决方案委托给solve
,并以一种可读的方式将其打印出来,或者作为“无解决方案”或者装饰精美的小鸡和猪。
现在,为了不断进步,问问自己是否可以更有效地编写solve
。很明显,如果腿的数量小于头数的两倍,或者是头数的四倍以上,或者奇数 - 可能solve
可以测试这些情况并返回{{1}立刻。你可以编码......?
这可能并不明显,但是头和腿的数量的每个其他组合都有一个解决方案 - 并且有一种方法可以通过算术找到它,而不需要循环。考虑一下,也许是在小学中学代数的帮助下......
答案 1 :(得分:2)
Alex Martelli提到了一个代数解决方案,我将在此处包含完整性。它可以通过使用联立方程来计算出来。作为一个简单的数学解决方案,它可能更快,至少对于大数量的腿和头: - )
让:
H
是头数; L
是腿的数量; C
是小鸡的数量;和P
是猪的数量。鉴于C
和P
,我们可以使用以下方法计算其他两个变量:
H = C + P (1)
L = 2C + 4P (2)
我将在下面的计算中详细说明每个步骤。数学倾向无疑可以指出步骤可以合并,但我更愿意明确。从(1),我们可以计算:
H = C + P
=> 0 = C + P - H [subtract H from both sides]
=> 0 = H - C - P [multiply both sides by -1]
=> P = H - C [add P to both sides] (3)
并将其替换为(2):
L = 2C + 4P
=> L = 2C + 4(H - C) [substitute H-C for P]
=> L = 2C + 4H - 4C [expand 4(H-C) to 4H-4C]
=> L = 4H - 2C [combine 2C-4C into -2C]
=> 0 = 4H - 2C - L [subtract L from both sides]
=> 2C = 4H - L [add 2C to both sides]
=> C = 2H - L/2 [divide both sides by 2] (4)
现在你有两个公式,一个可以计算头部和腿部的雏鸡数(4)
,另一个可以计算雏鸡和头部(3)
的猪数。
所以这里是Python代码,通过适当的检查确保你不允许一些更离奇的数学解决方案,比如2头7腿给我们一只半只小鸡和半只小鸡,或者1头和12腿给5头猪和-4只小鸡: - )
def solve (numLegs, numHeads):
# Use the formulae (these make integers).
chicks = numHeads * 2 - int (numLegs / 2)
pigs = numHeads - chicks
# Don't allow negative number of animals.
if chicks < 0 or pigs < 0:
return [None, None]
# Don't allow fractional animals.
if chicks * 2 + pigs * 4 != numLegs:
return [None, None]
if chicks + pigs != numHeads:
return [None, None]
return [pigs, chicks]
当然,如果你传入一些头部或腿部的数量,所有的赌注都会被取消。这是一个完整的测试程序,因此您可以尝试各种值以确保两个方法返回相同的值:
import sys
def usage (reason):
print "Error: %s"%(reason)
print "Usage: solve <numHeads> <numLegs>"
sys.exit (1);
def solve1 (numLegs, numHeads):
for numChicks in range (0, numHeads + 1):
numPigs = numHeads - numChicks
totLegs = 4 * numPigs + 2 * numChicks
if totLegs == numLegs:
return [numPigs, numChicks]
return [None, None]
def solve2 (numLegs, numHeads):
chicks = numHeads * 2 - int (numLegs / 2)
pigs = numHeads - chicks
if chicks < 0 or pigs < 0: return [None, None]
if chicks * 2 + pigs * 4 != numLegs: return [None, None]
if chicks + pigs != numHeads: return [None, None]
return [pigs, chicks]
if len (sys.argv) != 3:
usage ("Wrong number of parameters (%d)"%(len (sys.argv)))
try: heads = int (sys.argv[1])
except: usage ("Invalid <numHeads> of '%s'"%(sys.argv[1]))
try: legs = int (sys.argv[2])
except: usage ("Invalid <numLegs> of '%s'"%(sys.argv[2]))
print "[pigs, chicks]:"
print " ", solve1 (legs, heads)
print " ", solve2 (legs, heads)
答案 2 :(得分:1)
它正在迭代猪和鸡的每一种可能的组合(具有指定数量的头),直到找到具有正确腿数的一个,然后返回猪和鸡的数量。如果它在没有找到有效答案的情况下通过每个组合,则返回[None,None]以指示失败。
答案 3 :(得分:1)
基本上,solve
正在迭代鸡和猪的每一种可能组合,当它找到匹配时,返回它。)
NumChickens + NumPigs必须等于NumHeads,因此它会检查每个NumChickens从0到NumHeads(这是for range(0,NumHeads+1)
所做的),并将NumPigs设置为NumHeads-NumChickens。
从那里,只需要增加脚的数量,看看它们是否匹配。
答案 4 :(得分:1)
基本上,它正在试图找出问题的答案,“如果在谷仓里有X头和Y腿,那么在谷仓里有多少只鸡和猪?” for numChicks in range(0, numHeads + 1):
代码创建变量numChicks,并从numChicks = 0循环到numChicks = numHeads。 (注意:范围功能不包括最高值)。
对于每个numChicks数,它会检查numChicks和相应的numPigs值是否出现numLegs的正确值。 numHeads总是正确的,因为numChicks + numPigs = numHeads,但numLegs根据分布而变化 - 因此循环。如果在任何时候找到解决方案(当totLegs == numLegs时),则返回该值。如果整个循环完成并且没有找到解决方案,则返回列表[None,None],这意味着此输入没有解决方案。