Calcular un pedigrí

22

Una pequeña lección de genética

Cuando solo tiene acceso a los rasgos o fenotipos visibles de alguien, a menudo se utiliza un pedigrí de sus antecedentes familiares para determinar la información genética real o el genotipo de cada miembro de la familia.

Cuando se trata de un dominio simple como lo seremos, un simple cuadro genealógico será suficiente para descubrir los alelos, o la versión de los genes que tienen, de cada persona. En el dominio simple, una persona con un alelo dominante (denotado con una letra mayúscula) siempre tendrá el rasgo que esa versión representa, sin importar el otro alelo. Se necesitan dos alelos recesivos (denotados con una letra minúscula) para que se exprese esa versión. En otras palabras, el alelo dominante siempre enmascara la versión recesiva de ese gen. Aquí hay un ejemplo de un cuadro genealógico:

TABLA DE PEDIGREE

Cada fila aquí es una generación. Los círculos son femeninos, los cuadrados masculinos, las líneas horizontales son el matrimonio, las líneas verticales son los niños. Bastante simple. Negro significa fenotipo recesivo, blanco, dominante. Comenzando desde arriba, (supongamos que los alelos son Ay a), sabemos que la persona 2 tiene un aahomocigoto recesivo porque esa es la única opción posible para el fenotipo recesivo. Ahora, aunque la persona uno podría ser Aao AAser un fenotipo dominante, porque tiene un hijo recesivo, debe ser Aaheterocigótico. Puedes hacer esto para todas las demás personas. En el caso de que no tiene ninguna información que le permite averiguar el segundo alelo, se puede hacer de esta manera: A_.

Tu tarea

  • Recibirá un cuadro genealógico en forma de una lista de generaciones, como [GenI, GenII, etc.]en cualquier formato cuerdo.
  • Cada generación será una lista de cadenas, cada cadena representa una persona.
  • Las personas se componen de tres partes: una identificación, su fenotipo y sus "conexiones".
  • Su ID es un único carácter ascii imprimible que es único en todo el árbol que no sea Ao a. (No, no habrá más de 95 personas en la tabla).
  • Su fenotipo es uno de Ao a, Asiendo el alelo dominante y arecesivo.
  • Sus conexiones son una secuencia de identificaciones de otras personas con las que tienen conexiones.
  • Una conexión en la misma generación es el matrimonio, en diferentes generaciones es niño y padre.
  • Las conexiones se repiten en ambos lados (es decir, el esposo ha dicho que es esposo de esposa, y la esposa dice que ella es esposo de esposa).
  • Tienes que descubrir los genotipos de todos lo más posible.
  • Devuelva la misma lista, excepto que en lugar de personas, coloque sus genotipos en la misma posición.
  • El genotipo debe ser emitido en orden, en Aalugar de hacerlo aA.
  • Un poco de margen en el formato de entrada está bien.
  • Este es el código de golf, por lo que la respuesta más corta en bytes gana.

Ejemplos

[["0A1234", "1a0234"], ["2A01", "3a01", "4A015678",
"5a4678"], ["6a45", "7A45","8A45"]] (The one above)   ->

[["Aa", "aa"], ["Aa", "aa", "Aa", "aa"], ["aa", "Aa", "Aa"]]

[["0A12", "1A02"], ["2A301", "3a2"]]    ->

[["A_", "A_"], ["A_", "aa"]]

Prima

  • -30 bytes si se trata de incompleto y co-dominancia también. En la detección de tres fenotipos en lugar de dos en toda la tabla, aplique dominancia incompleta / co en su algoritmo.
Maltysen
fuente
¿Se nos permite modificar solo el Ay ay dejar los identificadores y las conexiones tal cual (es decir, se [["0A12","1A02"],["2A301","3a2"]]convierte en [["0A_12","1A_02"],["2A_301","3aa2"]]lugar de [["A_","A_"],["A_","aa"]])?
Kevin Cruijssen

Respuestas:

2

05AB1E , 39 bytes

εNUε'aåi„aaë¯.øX<X>‚è˜y2£lSδåPài„Aaë„A_

Puerto de mi respuesta Java .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

ε                     # Map over the rows of the (implicit) input-list:
 NU                   #  Store the outer-map index in variable `X`
   ε                  #  Map over the strings `y` of the current row:
    'aåi             '#   If the current string contains an "a":
        aa           #    Push string "aa"
       ë              #   Else (it contains an "A" instead):
        ¯.ø           #    Surround the (implicit) input-list with two empty lists
                      #    (05AB1E has automatic wrap-around when indexing lists,
                      #     so this is to prevent that)
           X<X>‚      #    Push `X-1` and `X+1` and pair them together
                è     #    Index both into the list to get (potential) parent and child rows
                 ˜    #    Flatten it to a single list
        y             #    Push the current string we're mapping again
         2£           #    Only leave the first 2 characters (its id and the letter "A")
           l          #    Lowercase the "A" to "a"
            S         #    And convert it to a list of characters: [id, "A"]
             δå       #    Check in each string whether it contains the id and "A"
               P      #    Check for each whether it contained BOTH the id AND "A"
                ài    #    If a child/parent is found for which this is truthy:
                  Aa #     Push string "Aa"
                 ë    #    Else:
                  A_ #     Push string "A_"
                      # (after which the mapped result is output implicitly)
Kevin Cruijssen
fuente
1

Java 10, 356 349 340 bytes

a->{int i=0,j,k,f,z=a.length;var r=new String[z][];for(;i<z;i++)for(r[i]=new String[j=a[i].length];j-->0;)if(a[i][j].contains("a"))r[i][j]="aa";else{var t=".a.*"+a[i][j].charAt(0)+".*";for(f=k=0;i>0&&k<a[i-1].length;)f=a[i-1][k++].matches(t)?1:f;for(k=0;i+1<z&&k<a[i+1].length;)f=a[i+1][k++].matches(t)?1:f;r[i][j]=f>0?"Aa":"A_";}return r;}

Pruébalo en línea.

Explicación general:

1) cualquiera a siempre se convertiráaa

2a) Si un niño Atiene padres aay A, se convertirá en Aa
2b) Si un niño Atiene padres Ay A, se convertirá en A_
2c) (No es posible que un niño Atenga padresaa y aa)

3a) Si un padre Atiene al menos un hijo a, se convertirá en Aa
3b) Si un padre Asolo tiene hijos A, se convertiráA_

Explicación del código:

a->{                     // Method with 2D String array as both parameter and return-type
  int i=0,j,k,           //  Index-integers
      f,                 //  Flag-integer
      z=a.length;        //  Length-integer
  var r=new String[z][]; //  Result 2D String array
  for(;i<z;i++)          //  Loop over the rows:
    for(r[i]=new String[j=a[i].length];
                         //   Create the inner String-array of the result
        j-->0;)          //   Loop over the columns:
      if(a[i][j].contains("a"))
                         //    If the current node contains "a":
        r[i][j]="aa";    //     Set the result at this node to "aa"
      else{              //    Else(-if the current node contains "A" instead):
        var t=".a.*"+a[i][j].charAt(0)+".*";
                         //     Set a temp String to a regex to check relations and "a"
        for(f=k=0;       //     Set the flag to 0
            i>0&&        //     If the current node has parents:
            k<a[i-1].length;)
                         //      Loop over the row above:
          f=a[i-1][k++].matches(t)?
                         //       If a parent with "a" is found:
            1:f;         //        Set the flag to 1 (else: leave it unchanged)
        for(k=0;i+1<z&&  //     If the current node has children:
            k<a[i+1].length;) 
                         //      Loop over the row below:
          f=a[i+1][k++].matches(t)?
                         //       If child with "a" is found:
            1:f;         //        Set the flag to 1 (else: leave it unchanged)
        r[i][j]=f>0?     //     If the flag is 1:
                 "Aa"    //      Current node changes from "A" to "Aa"
                :        //     Else (flag is still 0):
                 "A_";}  //      Current node changes from "A" to "A_"
  return r;}             //  Return the result
Kevin Cruijssen
fuente