Zrozumienie przykład

głosy
-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

Uczę Python i natknąłem się na ten przykład, może ktoś proszę wyjaśnić w prostym języku angielskim (lub pseudo-kod) co to robi wiersz po wierszu.

Wielkie dzięki

Utwórz 11/10/2009 o 05:08
źródło użytkownik
W innych językach...                            


5 odpowiedzi

głosy
1

Jest iteracja każdej możliwej kombinacji świnie i drób (z określonej liczby głowic), aż do stwierdzenia, że ​​jeden ma odpowiednią liczbę nóg, a następnie powraca do liczby świń i kurcząt. Jeśli robi się poprzez każdej kombinacji bez znalezienia prawidłowych odpowiedzi, powraca [None, None], aby wskazać błąd.

Odpowiedział 11/10/2009 o 05:15
źródło użytkownik

głosy
1

Zasadniczo, solvejest iteracja każdej możliwej kombinacji kurcząt i świń, a gdy znajdzie się dopasowanie, wpuszczeniem go).

NumChickens + NumPigs musi równać NumHeads, więc sprawdza co NumChickens od 0 do NumHeads (to co for range(0,NumHeads+1)robi), i ustawia NumPigs aby być NumHeads-NumChickens.

Stamtąd, to tylko kwestia mnożenie się liczby nogi i zobaczyć, czy są one zgodne.

Odpowiedział 11/10/2009 o 05:19
źródło użytkownik

głosy
8

solve jest obliczenie ile kurcząt (1 głowicy 2 nóg) i ile świnie (1 głowica 4 nogi) potrzebny do całkowitego do podanych ilości głowy i nóg.

Używa „brutalnej siły”, czyli maksymalnie prosty, podejście:

  • próbuje nawet możliwą liczbę piskląt od zera w ogóle aż został określony jako liczby głowic (to rola pętli for numChicks in range(0, numHeads + 1):, ponieważ rangedaje całkowite od wartości początkowej zalicza się do wartości końcowej wykluczonego);
  • za każde podane numChicksto oblicza ile świnie nie byłoby dać żądaną liczbę głowic, przez oświadczenienumPigs = numHeads - numChicks
  • następnie oblicza, ile ogółem nogi kurcząt i świń musiałby przez totLegs = 4*numPigs + 2*numChicks
  • Następnie sprawdza, czy totLegsrówna wnioskowana ilość: jeśli tak, to zwraca listę z dwóch elementów, liczba kurcząt i świń, które rozwiązują ten problem
  • Wreszcie, jeśli „spada z dołu” w forpętli bez powrócił jeszcze jakąś wartość, to wie, że nie ma rozwiązania, i oznacza, że wracając listę z których każdy ma dwa elementy None.

barnYardtylko delegaci Rozwiązaniem solve, i drukuje go w ładnym czytelny sposób, jako „brak” lub jako rozwiązanie ładnie urządzonych liczby kurcząt i świń.

Teraz, aby zachować postępuje, należy zadać sobie pytanie, czy solvemożna napisać bardziej wydajnie. Najwyraźniej nie ma rozwiązania, jeśli liczba nóg jest mniejsza niż dwukrotność liczby głowic, czyli ponad cztery razy liczba głowic, lub dziwne - może solvemógłby przetestować te sprawy i wrócić [None, None]natychmiast. Mógłbyś zakodować, że ...?

To może nie być oczywiste, ale każda inna kombinacja liczb głów i nóg ma rozwiązanie - i nie jest sposobem na znalezienie go tylko przez arytmetyki, bez pętli. Pomyśl o tym, być może z pomocą algebry elementarnej szkoły średniej ...

Odpowiedział 11/10/2009 o 05:22
źródło użytkownik

głosy
1

Zasadniczo, to stara się znaleźć odpowiedź na problem, „Ile kurczaki i świnie są tam w podwórze czy są głowice X i Y nogi w podwórze?” for numChicks in range(0, numHeads + 1):Kodu tworzy zmienne numChicks i cykle poprzez nią z numChicks = 0 numChicks = numHeads. (Uwaga: funkcja ta nie obejmuje zakres najwyższej wartości).

Dla każdej liczby numChicks, sprawdza, czy to numChicks i odpowiadające im wartości numPigs podchodzi z właściwą wartością numLegs. numHeads zawsze będzie prawidłowa od numChicks + numPigs = numHeads, ale numLegs zmienia się w zależności od rozkładu - stąd pętli. Jeśli w dowolnej chwili znajduje się w roztworze (gdy totLegs == numLegs), to wartość ta jest zwracana. Jeśli cała pętla zostanie zrobione i nie znaleziono rozwiązanie, lista [None, None] są zwracane, co oznacza, że ​​nie ma rozwiązania dla tego wejścia.

Odpowiedział 11/10/2009 o 05:22
źródło użytkownik

głosy
2

Alex Martelli nawiązuje do algebraicznego rozwiązanie, które będę tutaj należą do kompletności. Może być opracowane z wykorzystaniem równań. Będąc proste rozwiązanie matematycznego, to być może szybciej, przynajmniej dla dużych liczb nogach i głowach :-)

Pozwolić:

  • H być liczba głowic;
  • L jest liczbą nóg;
  • Cjest liczba kurcząt; i
  • P jest liczba świń.

Biorąc pod uwagę, Ci Pmożemy obliczyć pozostałe dwie zmienne z:

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

Będę szczegółowo każdy krok w poniższych obliczeniach. Niewątpliwie matematycznie skłonni można zauważyć, że kroki mogą być łączone, ale wolałbym być jawne. Z (1), możemy obliczyć:

   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)

i aby zastąpić w (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)

Teraz masz dwie formuły jeden, który można obliczyć liczbę piskląt z głowy i nóg (4), drugi, który może obliczyć liczbę świń z kurcząt i głów (3).

Więc oto kod Python to zrobić, odpowiednie kontrole w celu zapewnienia, że ​​nie pozwalają niektóre z bardziej dziwacznych rozwiązań matematycznych, jak 2 głów i 7 nóg dając nam świnię i pół wzdłuż z pół piskląt lub 1 głowę i 12 nogi zapewniające 5 świń i -4 piskląt :-)

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]

Oczywiście, jeśli przechodzą w liczbach ułamkowych głowy lub nóg, wszystkie zakłady są wyłączone. Oto kompletny program testowy, więc można wypróbować różne wartości, aby zapewnić obie metody zwraca te same wartości:

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)
Odpowiedział 12/10/2009 o 04:06
źródło użytkownik

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