Alex Martelli alude a una solución algebraica que incluiré aquí para completarla. Se puede resolver con el uso de ecuaciones simultáneas. Siendo una solución matemática simple, es posiblemente más rápido, al menos para un gran número de patas y cabezas :-)
Dejar:
H ser el número de cabezas;
L ser el número de piernas;
Cser el número de polluelos; y
P ser el número de cerdos.
Dado Cy P, podemos calcular las otras dos variables con:
H = C + P (1)
L = 2C + 4P (2)
Detallaré cada paso en los cálculos a continuación. Los matemáticamente inclinados sin duda pueden señalar que los pasos podrían combinarse, pero preferiría ser explícito. De (1), podemos calcular:
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)
y sustituirlo en (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)
Ahora tiene dos fórmulas, una que puede calcular el número de polluelos de la cabeza y las patas (4), la otra que puede calcular el número de cerdos de los polluelos y las cabezas (3).
Así que aquí está el código de Python para hacerlo, con las comprobaciones apropiadas para garantizar que no permita algunas de las soluciones matemáticas más extrañas, como 2 cabezas y 7 patas que nos dan un cerdo y medio junto con la mitad de un pollito, o 1 cabeza y 12 piernas dando 5 cerdos y -4 polluelos :-)
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]
Por supuesto, si pasas números fraccionarios de cabeza o piernas, todas las apuestas estarán desactivadas. Aquí hay un programa de prueba completo para que pueda probar varios valores para asegurarse de que ambos métodos devuelvan los mismos valores:
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)