import itertools from enum import unique, Enum @unique class BloodType(Enum): O_NEGATIVE = (0, 0, 0) # (a, b, sign) O_POSITIVE = (0, 0, 1) A_NEGATIVE = (1, 0, 0) A_POSITIVE = (1, 0, 1) B_NEGATIVE = (0, 1, 0) B_POSITIVE = (0, 1, 1) AB_NEGATIVE = (1, 1, 0) AB_POSITIVE = (1, 1, 1) def blood_cell_compatibility_lookup(recipient: BloodType, donor: BloodType) -> bool: """ https://en.wikipedia.org/wiki/Blood_type#Red_blood_cell_compatibility """ return { BloodType.O_NEGATIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: False, BloodType.A_NEGATIVE: False, BloodType.A_POSITIVE: False, BloodType.B_NEGATIVE: False, BloodType.B_POSITIVE: False, BloodType.AB_NEGATIVE: False, BloodType.AB_POSITIVE: False }, BloodType.O_POSITIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: True, BloodType.A_NEGATIVE: False, BloodType.A_POSITIVE: False, BloodType.B_NEGATIVE: False, BloodType.B_POSITIVE: False, BloodType.AB_NEGATIVE: False, BloodType.AB_POSITIVE: False }, BloodType.A_NEGATIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: False, BloodType.A_NEGATIVE: True, BloodType.A_POSITIVE: False, BloodType.B_NEGATIVE: False, BloodType.B_POSITIVE: False, BloodType.AB_NEGATIVE: False, BloodType.AB_POSITIVE: False }, BloodType.A_POSITIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: True, BloodType.A_NEGATIVE: True, BloodType.A_POSITIVE: True, BloodType.B_NEGATIVE: False, BloodType.B_POSITIVE: False, BloodType.AB_NEGATIVE: False, BloodType.AB_POSITIVE: False }, BloodType.B_NEGATIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: False, BloodType.A_NEGATIVE: False, BloodType.A_POSITIVE: False, BloodType.B_NEGATIVE: True, BloodType.B_POSITIVE: False, BloodType.AB_NEGATIVE: False, BloodType.AB_POSITIVE: False }, BloodType.B_POSITIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: True, BloodType.A_NEGATIVE: False, BloodType.A_POSITIVE: False, BloodType.B_NEGATIVE: True, BloodType.B_POSITIVE: True, BloodType.AB_NEGATIVE: False, BloodType.AB_POSITIVE: False }, BloodType.AB_NEGATIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: False, BloodType.A_NEGATIVE: True, BloodType.A_POSITIVE: False, BloodType.B_NEGATIVE: True, BloodType.B_POSITIVE: False, BloodType.AB_NEGATIVE: True, BloodType.AB_POSITIVE: False }, BloodType.AB_POSITIVE: { BloodType.O_NEGATIVE: True, BloodType.O_POSITIVE: True, BloodType.A_NEGATIVE: True, BloodType.A_POSITIVE: True, BloodType.B_NEGATIVE: True, BloodType.B_POSITIVE: True, BloodType.AB_NEGATIVE: True, BloodType.AB_POSITIVE: True }, }[recipient][donor] def blood_cell_compatibility_boolean(recipient: BloodType, donor: BloodType) -> bool: (ra, rb, rs), (da, db, ds) = recipient.value, donor.value return (ra or not da) and (rb or not db) and (rs or not ds) if __name__ == '__main__': green = 0 red = 0 for recipient, donor in itertools.product(BloodType, repeat=2): lookup = blood_cell_compatibility_lookup(recipient, donor) boolean = blood_cell_compatibility_boolean(recipient, donor) if lookup == boolean: green += 1 else: print(f"'{BloodType(donor).name} -> {BloodType(recipient).name}' should be {lookup}.") red += 1 print("Green:", green) print("Red :", red)