Compute Blood Types
Doing another painful irrelevant code question about inheritance and blood types and came up with this
Given
/**
* @param parent1 The phenotype of the first parent (A, B, AB or O)
* @param parent2 The phenotype of the second parent (A, B, AB or O)
* @param child The phenotype of the child (A, B, AB or O)
* @return A list of list of string, containing all the possible blood genes of the two parents.
*/
This means that if you have for instance, A and B are dominant and O
is only recessive therefore
- Parent1:
AB
- Parent2:
A
- Child:
A
The results are AB, AA or AB, AO
as in the second parent could have an O
gene or be a duplicate AA
. That is because the child produced is A
which is the way you check the parent possible outputs. As in the above there is no way for an O
child to be produced.
C#
public static List<List<string>> ComputeBloodGenes(string parent1, string parent2, string child)
{
var combos = (from p1 in NormalizeParent(parent1)
from p2 in NormalizeParent(parent2)
select new List<string> { p1, p2 }).ToList();
var validPairs = (from combo in combos
let firstParent = combo.First()
let secondParent = combo.Last()
let result1 = $"{firstParent[0]}{secondParent[0]}"
let result2 = $"{firstParent[0]}{secondParent[1]}"
let result3 = $"{firstParent[1]}{secondParent[1]}"
let result4 = $"{firstParent[1]}{secondParent[0]}"
where GetPhenoType(result1) == child ||
GetPhenoType(result2) == child ||
GetPhenoType(result3) == child ||
GetPhenoType(result4) == child
select combo).ToList();
if (validPairs.Count == 0)
{
validPairs.Add(["--", "--"]);
}
return validPairs;
List<string> NormalizeParent(string parent)
{
if (parent.Length != 1)
{
return [parent];
}
return parent switch
{
"A" => ["AA", "AO"],
"B" => ["BB", "BO"],
"O" => ["OO"],
_ => [parent]
};
}
string GetPhenoType(string input)
{
return input switch
{
"AA" or "AO" or "OA" => "A",
"BB" or "BO" or "OB" => "B",
"OO" => "O",
_ => "AB"
};
}
}
Python
from icecream import ic
def possible_parent_genes(phenotype: str) -> list[str]:
match phenotype:
case "A":
return ["AA", "AO"]
case "B":
return ["BB", "BO"]
case "AB":
return ["AB"]
case "O":
return ["OO"]
case _:
return []
def get_phenotype(input_gene: str) -> str:
match input_gene:
case input_gene if input_gene in ["AA", "AO", "OA"]:
return "A"
case input_gene if input_gene in ["BB", "BO", "OB"]:
return "B"
case input_gene if input_gene in ["AB", "BA"]:
return "AB"
case "OO":
return "O"
case _:
return ""
def compute_blood_lines(parent1: str, parent2: str, child: str) -> list[list[str]]:
combos = [
[p1, p2]
for p1 in possible_parent_genes(parent1)
for p2 in possible_parent_genes(parent2)
]
valid_pairs = [
combo
for combo in combos
if any(
get_phenotype(result) == child
for result in [
combo[0][0] + combo[1][0],
combo[0][0] + combo[1][1],
combo[0][1] + combo[1][1],
combo[0][1] + combo[1][0],
]
)
]
if not valid_pairs:
valid_pairs.append(["--", "--"])
return valid_pairs
if __name__ == "__main__":
ic(compute_blood_lines('AB', 'A', 'A'))
ic(compute_blood_lines('AB', 'A', 'O'))
ic(compute_blood_lines('A', 'O', 'O'))
ic| compute_blood_lines('AB', 'A', 'A'): [['AB', 'AA'], ['AB', 'AO']]
ic| compute_blood_lines('AB', 'A', 'O'): [['--', '--']]
ic| compute_blood_lines('A', 'O', 'O'): [['AO', 'OO']]