Понимание пример

голоса
-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

Я учусь на Python и наткнулся на этот пример, может кто-то пожалуйста, объясните, в простом английском языке (или псевдо-код), что это делает построчно.

Большое спасибо

Задан 11/10/2009 в 05:08
источник пользователем
На других языках...                            


5 ответов

голоса
1

Он перебор всех возможных комбинаций свиней и кур (с указанием количества голов) до тех пор, пока не найдет ту, которая имеет правильное число ног, а затем возвращает число свиней и кур. Если он получает через каждую комбинацию, не находя правильный ответ, он возвращает [None, None], чтобы указать отказ.

Ответил 11/10/2009 в 05:15
источник пользователем

голоса
1

По существу, solveитерация через все возможные комбинации кур и свиней, и , когда он находит совпадение, возвращая его.)

NumChickens + NumPigs должна равняться NumHeads, поэтому он проверяет каждые NumChickens от 0 до NumHeads (это то, что for range(0,NumHeads+1)делает), и устанавливает NumPigs , чтобы быть NumHeads-NumChickens.

Оттуда его только вопрос умножения из числа ног, и, видя, если они совпадают.

Ответил 11/10/2009 в 05:19
источник пользователем

голоса
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было бы проверить для тех случая и вернуться [None, None]немедленно. Не могли бы вы код , что ...?

Оно не может быть очевидным, но все остальные комбинации чисел головок и ножек имеет решение - и есть способ, чтобы найти его просто арифметика, без зацикливания. Подумайте об этом, может быть, с помощью элементарной средней школы алгебры ...

Ответил 11/10/2009 в 05:22
источник пользователем

голоса
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] не возвращаются, а это означает, что нет никакого решения для этого входа.

Ответил 11/10/2009 в 05:22
источник пользователем

голоса
2

Алекс Мартелли ссылается на алгебраическое решение , которое я включу здесь для полноты картины . Он может быть разработан с использованием одновременных уравнений. Будучи простым математическим решением, это , возможно , быстрее, по крайней мере , для больших чисел ног и головы :-)

Позволять:

  • 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)
Ответил 12/10/2009 в 04:06
источник пользователем

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