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