Berechnen Sie einen Stammbaum

22

Eine kleine Lektion in Genetik

Wenn Sie nur Zugriff auf die sichtbaren Merkmale oder den Phänotyp einer Person haben, wird häufig ein Stammbaum ihrer Familiengeschichte verwendet, um die tatsächliche genetische Information oder den Genotyp jedes Familienmitglieds herauszufinden .

Wenn wir uns mit einfacher Dominanz befassen , reicht ein einfaches Stammbaumdiagramm aus, um die Allele oder die Version der Gene, die sie haben, jeder Person herauszufinden. In der einfachen Dominanz hat eine Person mit einem dominanten Allel (mit einem Großbuchstaben bezeichnet) immer die Eigenschaft, die diese Version darstellt, unabhängig von dem anderen Allel. Es braucht zwei rezessive Allele (mit einem Kleinbuchstaben bezeichnet), um diese Version auszudrücken. Mit anderen Worten, das dominante Allel maskiert immer die rezessive Version dieses Gens. Hier ist ein Beispiel eines Stammbaums:

PEDIGREE-DIAGRAMM

Jede Reihe hier ist eine Generation. Kreise sind weiblich, Männer Quadrate, horizontale Linien sind Ehe, vertikale Linien Kinder. Ziemlich einfach. Schwarz bedeutet rezessiver Phänotyp, weiß, dominant. Ausgehend von der Spitze (angenommen, die Allele sind Aund a) wissen wir, dass Person 2 aahomozygot rezessiv ist, da dies die einzig mögliche Option für den rezessiven Phänotyp ist. Jetzt, obwohl Person man entweder sein Aaoder AAdominanter Phänotyp sein könnte, weil er ein rezessives Kind hat, muss er Aaheterozygot sein. Sie können dies für alle anderen Menschen tun. Im Fall , dass Sie keine Informationen haben , dass Sie das zweite Allel , um herauszufinden , ermöglicht, kann es wie so geschehen: A_.

Deine Aufgabe

  • Sie erhalten eine Ahnentafel in Form einer Liste von Generationen wie [GenI, GenII, etc.]in jedem vernünftigen Format.
  • Jede Generation wird eine Liste von Zeichenfolgen sein, wobei jede Zeichenfolge eine Person darstellt.
  • Die Menschen bestehen aus drei Teilen - einer ID, ihrem Phänotyp und ihren "Verbindungen".
  • Ihre ID ist ein einzelnes druckbares ASCII-Zeichen, das in der gesamten Struktur außer Aoder eindeutig ist a. (Nein, das Diagramm enthält nicht mehr als 95 Personen.)
  • Ihr Phänotyp ist einer von Aoder a, Adas dominierende Allel zu sein und arezessiv zu sein.
  • Ihre Verbindungen sind eine Folge von IDs anderer Personen, mit denen sie Verbindungen haben.
  • Eine Verbindung in der gleichen Generation ist die Ehe, in verschiedenen Generationen sind Kind und Eltern.
  • Die Verbindungen wiederholen sich auf beiden Seiten (dh der Ehemann sagt, er sei ein Ehemann der Ehefrau, und die Ehefrau sagt, sie sei ein Ehemann der Ehefrau).
  • Sie müssen die Genotypen aller so gut wie möglich herausfinden.
  • Geben Sie dieselbe Liste zurück, mit der Ausnahme, dass anstelle von Personen deren Genotypen an derselben Position platziert werden.
  • Der Genotyp hat , um so ausgegeben werden , Aastatt aA.
  • Ein wenig Spielraum beim Eingabeformat ist in Ordnung.
  • Dies ist Code-Golf, also gewinnt die kürzeste Antwort in Bytes .

Beispiele

[["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"]]

Bonus

  • -30 Bytes, wenn Sie auch mit Unvollständigkeit und Co-Dominanz zu tun haben . Wenden Sie beim Erkennen von drei anstelle von zwei Phänotypen im gesamten Diagramm die Unvollständigkeit / Ko-Dominanz auf Ihren Algorithmus an.
Maltysen
quelle
Dürfen wir nur ändern das Aund aund lassen Sie die IDs und Verbindungen wie (dh [["0A12","1A02"],["2A301","3a2"]]wird [["0A_12","1A_02"],["2A_301","3aa2"]]statt [["A_","A_"],["A_","aa"]])?
Kevin Cruijssen

Antworten:

2

05AB1E , 39 Bytes

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

Port meiner Java-Antwort .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

ε                     # 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
quelle
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;}

Probieren Sie es online aus.

Allgemeine Erklärung:

1) Jeder awird immer werdenaa

2a) Wenn ein Kind AEltern hat aaund Awird Aa
2b) Wenn ein Kind AEltern hat Aund Awird A_
2c) (Es ist nicht möglich, dass ein Kind AEltern hat aaund aa)

3a) Wenn ein Elternteil Amindestens ein Kind hat a, wird es Aa
3b) Wenn ein Elternteil Anur Kinder hat A, wird esA_

Code Erklärung:

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
quelle