124 lines
4.1 KiB
Python
124 lines
4.1 KiB
Python
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)
|