Skip to content

Instantly share code, notes, and snippets.

@youssef3wi
Created February 10, 2024 11:48
Show Gist options
  • Select an option

  • Save youssef3wi/d6d6c7428e61d9df9a752f97f5db3b8a to your computer and use it in GitHub Desktop.

Select an option

Save youssef3wi/d6d6c7428e61d9df9a752f97f5db3b8a to your computer and use it in GitHub Desktop.
You have to list all the gene combinations of two parents, from their blood type and the blood type of one of their children.

Goal

You have to list all the gene combinations of two parents, from their blood type and the blood type of one of their children.

Description

Each person has two blood genes, each of them can be A, B or O.

You do not directly know which person has which genes, but you know their phenotypes (the apparent expression of the genes). The phenotype can be: A, B, AB or O.

Here are the correspondences between blood genes and phenotype:

  • When the two genes of a person are both "A", the phenotype is "A".

  • When the genes are both "B", the phenotype is "B".

  • When the genes are both "O", the phenotype is "O".

  • When one gene is "A" and the other is "B", the phenotype is "AB".

  • When one gene is "A" and the other is "O", the phenotype is "A".

  • When one gene is "B" and the other is "O", the phenotype is "B".

blood gene 1

A

B

O

blood gene 2

A

A

AB

A

B

AB

B

B

O

A

B

O

Phenotype

A child gets one of the blood genes from their first parent, and the other one from their second parent. The genes are randomly chosen.

You are given the phenotypes of three persons: first parent, second parent, and one of their children.

Output a list, containing all the possible blood gene combinations of the parents. Each element of the list is a sub-list of two strings, containing the blood genes of the first and second parent, in that order.

When there is no possible combination, output a list containing only one element: a sub-list of two strings, both equal to -- (two hyphens).

Since the order of genes is not important inside one person, you do not have to describe "BO or OB". So, each string will always have one of the following values: AA, BB, AB, AO, BO, OO, --.

The elements in the main list must be alphabetically sorted by the first parent genes, then by the second parent genes.

Example 1

You get these values in input:

parent_1 = "AB"
parent_2 = "A"
child = "A"
  • The phenotype of the first parent is "AB", so the blood genes are "AB" (only one possible value).

  • The phenotype of the second parent is "A". so the blood genes can be "AA" or "AO"

The first parent combination is ["AB", "AA"]. Each of the parents can give a blood gene "A" to the child. The child would have the phenotype "A". It is possible.

The second parent combination is ["AB", "AO"]. The first parent can give the blood gene "A", the second one can give any of the blood genes. The child would have the blood genes "AA" or "AO", in both cases it results in the phenotype "A". It is possible.

You have to output the following value : [["AB", "AA"], ["AB", "AO"]]

Example 2

You get these values in input:

parent_1 = "O"
parent_2 = "AB"
child = "O"
  • The phenotype of the first parent is "O", so tbe blood genes are "OO" (only one possible value).

  • The phenotype of the second parent is "AB", so the blood genes are "AB" (only one possible value).

The first parent always gives a blood gene "O" to the child, the second one gives either an "A" or a "B".

In the first case, the blood genes of the child would be "AO", which results in the phenotype "A". In the second case, the blood genes would be "BO", which results in the phenotype "B". But the child has the phenotype "O". So it is impossible.

You have to output the following value: [["--", "--"]]

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.util.Collections.singletonList;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
/**
* <p><b>Goal</b></p>
* You have to list all the gene combinations of two parents, from their blood type and
* the blood type of one of their children.
* <p><b>Description</b></p>
* Each person has two <b>blood genes</b>, each of them can be <mark>A</mark>, <mark>B</mark> or <mark>O</mark>.
* <p>
* You do not directly know which person has which genes, but you know their <b>phenotypes</b>
* (the apparent expression of the genes). The phenotype can be: A, B, AB or O.
* <p>
* Here are the correspondences between blood genes and phenotype:
* <ul>
* <li>When the two genes of a person are both "A", the phenotype is "A".</li>
* <li>When the genes are both "B", the phenotype is "B".</li>
* <li>When the genes are both "O", the phenotype is "O".</li>
* <li>When one gene is "A" and the other is "B", the phenotype is "AB".</li>
* <li>When one gene is "A" and the other is "O", the phenotype is "A".</li>
* <li>When one gene is "B" and the other is "O", the phenotype is "B".</li>
* </ul>
* <table border="1">
* <tr>
* <td colspan="2"></td>
* <td colspan="3">blood gene 1</td>
* </tr>
* <tr>
* <td></td>
* <td></td>
* <td>A</td>
* <td>B</td>
* <td>O</td>
* </tr>
* <tr>
* <td rowspan="3">blood gene 2</td>
* <td>A</td>
* <td>A</td>
* <td>AB</td>
* <td>A</td>
* </tr>
* <tr>
* <td>B</td>
* <td>AB</td>
* <td>B</td>
* <td>B</td>
* </tr>
* <tr>
* <td>O</td>
* <td>A</td>
* <td>B</td>
* <td>O</td>
* </tr>
* <tr>
* <td></td>
* <td></td>
* <td colspan="3">Phenotype</td>
* </tr>
* </table>
* A child gets one of the blood genes from their first parent, and the other one from
* their second parent. The genes are randomly chosen.
* <p>
* You are given the phenotypes of three persons: first parent, second parent, and one
* of their children.
* <p>
* Output a list, containing all the possible blood gene combinations of the parents.
* Each element of the list is a sub-list of two strings, containing the blood genes of
* the first and second parent, in that order.
* <p>
* When there is no possible combination, output a list containing only one element: a sub-list
* of two strings, both equal to <mark>--</mark> (two hyphens).
* <p>
* Since the order of genes is not important inside one person, you do not have to describe
* "BO or OB". So, each string will always have one of the following values:
* AA, BB, AB, AO, BO, OO, --.
* <p>
* <b>The elements in the main list must be alphabetically sorted by the first parent genes,
* then by the second parent genes.</b>
* <p>
* <b>Example 1</b>
* <p>You get these values in input:</p>
* <code>
* parent_1 = "AB"<br/>
* parent_2 = "A"<br/>
* child = "A"<br/>
* </code>
* <ul>
* <li>The phenotype of the first parent is "AB", so the blood genes are "AB" (only one possible value).</li>
* <li>The phenotype of the second parent is "A". so the blood genes can be "AA" or "AO"</li>
* </ul>
* The first parent combination is ["AB", "AA"]. Each of the parents can give a blood
* gene "A" to the child. The child would have the phenotype "A". It is possible.
* <p>
* The second parent combination is ["AB", "AO"]. The first parent can give the blood
* gene "A", the second one can give any of the blood genes. The child would have the
* blood genes "AA" or "AO", in both cases it results in the phenotype "A". It is possible.
* <p>
* You have to output the following value : [["AB", "AA"], ["AB", "AO"]]
* <p>
* <b>Example 2</b>
* <p>You get these values in input:</p>
* <code>
* parent_1 = "O"<br/>
* parent_2 = "AB"<br/>
* child = "O"<br/>
* </code>
* <ul>
* <li>The phenotype of the first parent is "O", so tbe blood genes are "OO" (only one possible value).</li>
* <li>The phenotype of the second parent is "AB", so the blood genes are "AB" (only one possible value).</li>
* </ul>
* The first parent always gives a blood gene "O" to the child, the second one gives
* either an "A" or a "B".
* <p>
* In the first case, the blood genes of the child would be "AO", which results in the
* phenotype "A". In the second case, the blood genes would be "BO", which results in
* the phenotype "B".
* <p>
* But the child has the phenotype "O". So it is impossible.
* <p>
* You have to output the following value: [["--", "--"]]
*/
public class GeneCombinations {
private static Map<String, String> phenotypes = new HashMap<>();
private static Map<String, List<String>> genesByPhenotype = new HashMap<>();
private static final List<String> EMPTY_GENE = unmodifiableList(Arrays.asList("--", "--"));
static {
phenotypes.put("AA", "A");
phenotypes.put("AO", "A");
phenotypes.put("BB", "B");
phenotypes.put("BO", "B");
phenotypes.put("AB", "AB");
phenotypes.put("OO", "O");
genesByPhenotype.put("A", Arrays.asList("AA", "AO"));
genesByPhenotype.put("B", Arrays.asList("BB", "BO"));
genesByPhenotype.put("AB", singletonList("AB"));
genesByPhenotype.put("O", singletonList("OO"));
genesByPhenotype = unmodifiableMap(genesByPhenotype);
phenotypes = unmodifiableMap(phenotypes);
}
/**
* @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 string, containing all the possible blood genes of the two parents.
*/
public static List<List<String>> computeBloodGenes(String parent1, String parent2, String child) {
List<List<String>> results = new ArrayList<>();
// Calculate combinations
List<String> parent1Phenotypes = genesByPhenotype.get(parent1);
List<String> parent2Phenotypes = genesByPhenotype.get(parent2);
build_combinations:
for (String parent1Phenotype : parent1Phenotypes) {
for (String parent2Phenotype : parent2Phenotypes) {
// Check combinations with the child
boolean goodGene = false;
check_combinations:
for (int idx = 0; idx < parent1Phenotype.length(); idx++) {
for (int jdx = 0; jdx < parent2Phenotype.length(); jdx++) {
char[] genes = {parent1Phenotype.charAt(idx), parent2Phenotype.charAt(jdx)};
Arrays.sort(genes);
if (phenotypes.get(new String(genes)).equals(child)) {
goodGene = true;
break check_combinations;
}
}
}
if (!goodGene) {
results.clear();
break build_combinations;
}
// Add the combinations
results.add(Arrays.asList(parent1Phenotype, parent2Phenotype));
}
}
if (results.isEmpty()) {
results.add(EMPTY_GENE);
}
return results;
}
public static void main(String[] args) {
System.out.println("(AB, A, A) = " + computeBloodGenes("AB", "A", "A"));
System.out.println("(O, AB, O) = " + computeBloodGenes("O", "AB", "O"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment