理解examp

2024-06-28 18:54:54 发布

您现在位置:Python中文网/ 问答频道 /正文

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,遇到了这个例子,有人能用简单的英语(或伪代码)逐行解释一下它在做什么吗。在

非常感谢


Tags: nonereturnifdefprintheadssolvelegs
3条回答

alexmartelli提到了一个代数解,为了完整起见,我将在这里包含它。它可以用联立方程组来计算。作为一个简单的数学解,它可能会更快,至少对于腿和头的数目来说是如此

让:

  • H为人头数
  • L为支腿数
  • C是鸡的数量;和
  • P是猪的数量。在

给定C和{},我们可以用以下公式计算其他两个变量:

H =  C +  P (1)
L = 2C + 4P (2)

我将在下面的计算中详细说明每个步骤。数学上的倾向无疑可以指出步骤是可以组合的,但我更希望是明确的。从(1)可以计算:

^{pr2}$

将其代入(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)

它遍历每一个可能的猪和鸡的组合(具有指定数量的头),直到找到一个具有正确数量的腿,然后返回猪和鸡的数量。如果它通过每个组合而没有找到有效答案,它将返回[None,None]来指示失败。在

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是否可以更有效地编写。显然,如果腿的数量小于头部数量的两倍,或者超过头部数量的四倍,或者奇数,那么没有解决方案,也许{}可以测试这些情况并立即返回{}。你能把它编码成。。。?在

这可能并不明显,但是其他每一个头部和腿部的组合都有一个解决方案——而且有一种方法可以通过算术来找到它,而不需要循环。想一想,也许借助小学初中代数。。。在

相关问题 更多 >