理解一个例子

时间:2009-10-11 04:08:10

标签: python pseudocode

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并且遇到了这个例子,有人可以用简单的英语(或伪代码)解释这是逐行的。

非常感谢

5 个答案:

答案 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是猪的数量。

鉴于CP,我们可以使用以下方法计算其他两个变量:

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],这意味着此输入没有解决方案。