Skip to content

Instantly share code, notes, and snippets.

@zachwhaley
Created February 19, 2015 13:21
Show Gist options
  • Save zachwhaley/c1aae7f72f2d8f137922 to your computer and use it in GitHub Desktop.
Save zachwhaley/c1aae7f72f2d8f137922 to your computer and use it in GitHub Desktop.
Pair mating bears and avoid common ancestors
import sys
import re
class Bear:
def __init__(self, attrs):
self.parents = []
self.name = attrs[0]
if len(attrs) > 1:
self.sex = attrs[1]
self.parents = attrs[2:4]
self.age = float(attrs[4])
def read_file(file_):
with open(file_) as f:
for line in f:
yield [b.strip() for b in line.split(':')]
def norml(name):
return ' '.join(name.split()).upper()
def create_bears(file_):
pnts = set()
bears = {}
for line in read_file(file_):
# create bear for each line
name = norml(line[0])
bears[name] = Bear(line)
# create parents if they don't exist
pnts = pnts | set(map(norml, line[2:4]))
for pnt in [p for p in line[2:4] if norml(p) not in bears]:
bears[norml(pnt)] = Bear([pnt])
# set bear parents
set_parents(bears)
return [b for n, b in bears.iteritems() if n not in pnts]
def set_parents(bears):
for bear in bears.itervalues():
bear.parents = [bears[norml(pnt)] for pnt in bear.parents if pnt]
def mate_bears(bears):
boys, girls = find_mates(bears)
return [(b, g) for b in boys for g in girls if can_mate(b, g)]
def find_mates(bears):
boys = []
girls = []
for b in bears:
if b.age > 2.0 and b.age < 6.0:
if b.sex == 'M':
boys.append(b)
else:
girls.append(b)
return boys, girls
def can_mate(boy, girl):
return not are_related(boy, girl) and abs(boy.age - girl.age) <= 1.0
def are_related(boy, girl):
bped = pedigree(boy, [])
gped = pedigree(girl, [])
return len(bped & gped) > 0
def pedigree(bear, ped=[], gen=0):
pnts = bear.parents
if gen < 2:
ped += pnts
for p in pnts:
pedigree(p, ped, gen+1)
return set(ped)
def main(file_):
chldn = create_bears(file_)
mates = mate_bears(chldn)
for boy, girl in mates:
print ' + '.join([boy.name, girl.name])
if __name__=='__main__':
main(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment