سؤال

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

أنا أتعلم بيثون وصادف هذا المثال ، هل يمكن لشخص ما أن يوضح باللغة الإنجليزية البسيطة (أو الكود الزائف) ما الذي يفعله هذا الخط حسب الخط.

شكرا جزيلا

هل كانت مفيدة؟

المحلول

solve يتم حساب عدد الفراخ (رأس واحد ، ساقين) وعدد الخنازير (رأس واحد ، 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] فورا. هل يمكنك رمز ذلك ...؟

قد لا يكون ذلك واضحًا ، لكن كل مجموعة أخرى من أعداد الرؤوس والساقين لها حل - وهناك طريقة للعثور عليه فقط عن طريق الحساب ، دون حلقة. فكر في الأمر ، ربما بمساعدة جبر المدارس المتوسطة الابتدائية ...

نصائح أخرى

يلمح أليكس مارتيلي إلى حل جبري سأدرجه هنا من أجل الاكتمال. يمكن وضعه مع استخدام المعادلات المتزامنة. كونه حلًا رياضيًا بسيطًا ، فربما يكون أسرع ، على الأقل ل كبير أعداد الساقين والرؤوس :-)

يترك:

  • 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 للقيام بذلك ، مع الشيكات المناسبة للتأكد من أنك لا تسمح لبعض الحلول الرياضية الأكثر غرابة ، مثل الرؤساء و 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)

إنه يكرر من خلال كل مجموعة ممكنة من الخنازير والدجاج (مع العدد المحدد من الرؤوس) حتى يجد واحدة لديها العدد الصحيح من الأرجل ، ثم يعيد أعداد الخنازير والدجاج. إذا تمر عبر كل مجموعة دون العثور على إجابة صالحة ، فإنها تعود [لا شيء ، لا شيء] للإشارة إلى الفشل.

بشكل أساسي، solve هل يكرر كل مجموعة ممكنة من الدجاج والخنازير ، وعندما يجد تطابقًا ، وإعادته.)

يجب على numchickens + numpigs مساواة الأرقام ، بحيث يتحقق من كل numchickens من 0 إلى numheads (هذا ما for range(0,NumHeads+1) هل) ، ويضع numpigs ليكون numheads-numchickens.

من هناك ، إنها مجرد مسألة ضرب عدد القدمين ، ومعرفة ما إذا كانت تتطابق.

في الأساس ، تحاول معرفة الإجابة على المشكلة ، "كم عدد الدجاج والخنازير الموجودة في الفناء إذا كان هناك رؤوس 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) ، يتم إرجاع هذه القيمة. إذا تم الانتهاء من الحلقة بأكملها ولم يتم العثور على حل ، فسيتم إرجاع القائمة [لا شيء ، لا شيء] ، مما يعني أنه لا يوجد حل لهذا المدخلات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top