Match blood types in C
Each blood factor can be present or not present.  The blood types can be bit-encoded using one bit for the A factor, one bit for the B factor, and one bit for the Rh factor.

enum { A=1, B=2, Rh=4 };


You would parse the blood type "AB+" as A + B + Rh == 7, and "O-" as 0 because it does not contain any A factor, B factor, or Rh factor.

Survival requires the donor's blood not contain any factors missing in the recipient's blood type.  Compliment the recipient's blood type to get the bad factors, and use a bit-wise and operation to test that all of the factors are not present in the donor's blood.

bool donor_matches = (donor &amp; ~recipient) == 0;




If you want to leave you enum's as encoding the 4 blood types, and the Rh factor separately, you can get to a similar coding.

Note that:

enum { O, A, B, AB } abo;


will define O=0, A=1, B=2, AB=3, so you have a similar bit assignment as above.  The Rh factor on the other hand would be better to reverse the order:

enum { M, P } rh;


so that M=0, P=1.  Now you could express the match condition:

bool donor_match = (donor_abo &amp; ~recipient_abo) == 0 &amp;&amp; (donor_rh &amp; ~recipient_rh) == 0;




Finally, if you want to leave the rh enum as you have originally defined it:

enum { P, M } rh;


then note that donor_rh &gt;= recipient_rh would express that the rh factors match, or the donor has a less-restrictive (numerically higher) rh factor.