Het begrijpen van een voorbeeld

stemmen
-1
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

Ik ben aan het leren Python en kwam over dit voorbeeld, kan iemand uitleggen in gewoon Engels (of pseudo-code) wat dit doet regel voor regel.

Erg bedankt

De vraag is gesteld op 11/10/2009 om 05:08
bron van user
In andere talen...                            


5 antwoorden

stemmen
1

Het itereren door elke mogelijke combinatie van varkens en kippen (met het aangegeven aantal koppen) totdat er een wordt gevonden dat het juiste aantal benen heeft, en vervolgens het aantal varkens en kippen retourneert. Als het door elke combinatie krijgt zonder het vinden van een geldig antwoord, retourneert [None, None] om storing.

antwoordde op 11/10/2009 om 05:15
bron van user

stemmen
1

In wezen solvewordt itereren door elke mogelijke combinatie van kippen en varkens, en wanneer een overeenkomst wordt gevonden, terug te zenden.)

NumChickens + NumPigs moet NumHeads gelijk, dus controleert elke NumChickens van 0 tot NumHeads (dat is wat for range(0,NumHeads+1)doet), en stelt NumPigs om NumHeads-NumChickens zijn.

Vanaf daar, het is gewoon een kwestie van vermenigvuldiging uit het aantal voeten, en te kijken of ze overeenkomen.

antwoordde op 11/10/2009 om 05:19
bron van user

stemmen
8

solve berekent hoeveel kuikens (1 hoofd, 2 benen) en het aantal varkens (1 hoofd, benen 4) nodig is om oplopen tot het opgegeven aantal koppen en poten.

Het maakt gebruik van een "brute kracht", dat wil zeggen maximaal eenvoudig, aanpak:

  • probeert het zelfs mogelijk aantal kuikens van helemaal geen tot zo veel als is opgegeven als het aantal koppen (dat is de rol van de lus for numChicks in range(0, numHeads + 1):, omdat rangegeeft gehele getallen van de startwaarde opgenomen om de eindwaarde uitgesloten);
  • voor elke gegeven numChicksberekent hoeveel varkens er zou zijn om het gevraagde aantal koppen te geven, door de verklaringnumPigs = numHeads - numChicks
  • Vervolgens berekent hij hoeveel totale benen zouden die kuikens en varkens, door totLegs = 4*numPigs + 2*numChicks
  • Vervolgens controleert zij of de totLegsgelijke het gevraagde aantal: zo ja, het is een lijst terug met twee punten, het aantal kuikens en varkens die het probleem op te lossen
  • Tot slot, als het "valt van de onderkant" van de forlus zonder een waarde toch teruggekeerd, weet er is geen oplossing, en geeft aan dat door het terugsturen van een lijst waarvan elk van de twee items is None.

barnYardnet afgevaardigden de oplossing voor solve, en drukt het uit in een prettig leesbare manier, hetzij als "geen oplossing" of als mooi ingericht aantallen kuikens en varkens.

Nu, om te houden vordert, vraag jezelf af of solveefficiënter zou kunnen worden geschreven. Het is duidelijk dat er geen oplossing als het aantal poten is minder dan tweemaal het aantal koppen, of meer dan vier keer het aantal koppen, of oneven is - misschien solvekonden testen voor die zaak en terug te keren [None, None]onmiddellijk. Zou je die code ...?

Het is niet altijd duidelijk, maar elke andere combinatie van cijfers van hoofden en benen heeft een oplossing - en er is een manier om het te vinden door gewoon rekenen, zonder looping. Denk er eens over, misschien met de hulp van elementaire middelbare school algebra ...

antwoordde op 11/10/2009 om 05:22
bron van user

stemmen
1

Kortom, het is het proberen om erachter te komen het antwoord op het probleem, "Hoeveel kippen en varkens zijn er in een boerenerf als er X koppen en Y benen op het erf?" De for numChicks in range(0, numHeads + 1):code wordt een variabele numChicks en doorloopt het van numChicks = 0 tot numChicks = numHeads. (Let op: het bereik functie omvat niet de hoogste waarde).

Voor elk aantal numChicks, controleert deze of dat numChicks en bijbehorende numPigs waarden komt met de juiste waarde van numLegs. numHeads altijd juist aangezien numChicks + numPigs = numHeads, maar numLegs varieert op basis van de verdeling - vandaar de lus. Als op enig moment de oplossing wordt gevonden (bij totLegs == numLegs) dan die waarde wordt geretourneerd. Als de hele lus wordt gedaan en er geen oplossing is gevonden, dan wordt de lijst [None, None] terug, wat betekent dat er geen oplossing voor deze ingang.

antwoordde op 11/10/2009 om 05:22
bron van user

stemmen
2

Alex Martelli zinspeelt op een algebraïsche oplossing die ik hier zal omvatten voor de volledigheid. Het kan worden uitgewerkt onder toepassing van simultane vergelijkingen. Omdat het een eenvoudige wiskundige oplossing, het is misschien sneller, althans voor grote aantallen benen en hoofden :-)

Laat:

  • H zijn het aantal koppen;
  • L is het aantal draden;
  • Cis het aantal kuikens; en
  • P 'het aantal varkens.

Gegeven Cen Pkunnen we de andere twee variabelen te berekenen met:

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

Ik zal detail elke stap in de onderstaande berekeningen. De mathematisch geneigd kan geen twijfel over bestaan wijzen erop dat er stappen kunnen worden gecombineerd, maar ik heb liever expliciet te zijn. Van (1), kunnen we berekenen:

   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)

en vervangende die in (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)

Nu heb je twee formules, die het aantal kuikens uit het hoofd en benen kan berekenen (4), de andere welk aantal varkens uit kuikens en hoofden kan berekenen (3).

Dus hier is de Python-code om het te doen, met de nodige controles te zorgen dat u niet enkele van de meer bizarre wiskundige oplossingen maken het mogelijk, zoals 2 koppen en 7 legs geeft ons een varken en een half samen met de helft van een kuiken of 1 kop en 12 benen 5 geeft varkens en kuikens -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]

Natuurlijk, als je langs in gebroken getallen van het hoofd of benen, alle weddenschappen af. Hier is een volledige test programma, zodat u kunt uitproberen verschillende waarden om ervoor te zorgen beide methoden terug te keren dezelfde waarden:

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)
antwoordde op 12/10/2009 om 04:06
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more