men = [ "Grouper", "Trout", "Ray", "Mackerel", "Snapper", "Bass" ] # Rule functions return a boolean indicating if the rule denies the organisation. def rule1(org): """Grouper won't be an officer unless Snapper is President""" if "Grouper" in org and org.pres != "Snapper": return False return True def rule2(org): """Trout won't serve if he outranks Ray""" # Assume that rank is pres > vp > sec. # Also that if Ray does not serve, Trout is happy to serve if "Trout" in org and "Ray" in org and org["Trout"] > org["Ray"]: return False return True def rule3(org): """Trout won't serve with Bass under any conditions""" if "Trout" in org and "Bass" in org: return False return True def rule4(org): """Ray won't serve with both Snapper & Bass""" if "Ray" in org and "Snapper" in org and "Bass" in org: return False return True def rule5(org): """Ray won't serve if Bass is President or Trout is secretary""" if "Ray" in org and (org.pres == "Bass" or org.sec == "Trout"): return False return True def rule6(org): """Mackerel won't serve with Ray or Snapper unless he outranks him""" # Assume that Mackerel wants > (Ray | Snapper) if "Mackerel" in org and ("Ray" in org and org["Mackerel"] < org["Ray"] or "Snapper" in org and org["Mackerel"] < org["Snapper"]): return False return True def rule7(org): """Snapper won't be Vice-President""" if org.vp == "Snapper": return False return True def rule8(org): """Snapper won't be secretary if Mackerel is an officer""" if org.sec == "Snapper" and "Mackerel" in org: return False return True def rule9(org): """Snapper won't serve with Grouper unless Bass serves too""" if "Snapper" in org and "Grouper" in org and "Bass" not in org: return False return True def rule10(org): """Bass won't serve unless either he or Ray is President""" if "Bass" in org and org.pres != "Bass" and org.pres != "Ray": return False return True rules = [ rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule8, rule9, rule10 ] class Organisation(object): def __init__(self, pres, vp, sec): self.pres = pres self.vp = vp self.sec = sec def __contains__(self, item): return (self.pres == item or self.vp == item or self.sec == item) def __getitem__(self, key): if self.pres == key: return 3 elif self.vp == key: return 2 elif self.sec == key: return 1 else: raise IndexError("Organisation does not contain %s" % key) def __str__(self): return "pres: %s, vp: %s, sec: %s" % (self.pres, self.vp, self.sec) # Generate list of all possible organisations orgs = [] pres_choices = list(men) for pres in pres_choices: vp_choices = list(pres_choices) vp_choices.remove(pres) for vp in vp_choices: sec_choices = list(vp_choices) sec_choices.remove(vp) for sec in sec_choices: org = Organisation(pres, vp, sec) orgs.append(org) # Check the list against the rules and chuck out all that don't apply for i, rulefunc in enumerate(rules): print; print "Evaluating rule %d\n'%s':" % (i + 1, rulefunc.__doc__) remaining_orgs = [] for org in orgs: if rulefunc(org): remaining_orgs.append(org) else: print " Disallows " + str(org) orgs = remaining_orgs print; print "Organisations which pass all rules:" for org in orgs: print org