Oblicz rodowód

22

Mała lekcja genetyki

Kiedy masz dostęp tylko do widocznych cech lub fenotypu danej osoby, rodowód z jej historii rodzinnej jest często wykorzystywany do ustalenia faktycznej informacji genetycznej lub genotypu każdego członka rodziny.

Gdy mamy do czynienia z prostą dominacją, jaką będziemy, wystarczy prosty wykres rodowodowy, aby obliczyć allele lub wersję genów, które mają, każdej osoby. W zwykłej dominacji osoba z dominującym allelem (oznaczona wielką literą) zawsze będzie miała cechę, którą reprezentuje ta wersja, bez względu na inny allel. Wyrażenie tej wersji wymaga dwóch recesywnych alleli (oznaczonych małą literą). Innymi słowy, dominujący allel zawsze maskuje recesywną wersję tego genu. Oto przykład schematu rodowodowego:

TABELA RODOWODÓW

Każdy rząd tutaj jest pokoleniem. Kręgi to kobiety, kwadraty mężczyzn, poziome linie to małżeństwo, pionowe linie dzieci. Dość proste. Czarny oznacza fenotyp recesywny, biały, dominujący. Zaczynając od góry (zakładając, że allele są Ai a), wiemy, że osoba 2 ma aahomozygotyczny recesywny, ponieważ jest to jedyna możliwa opcja fenotypu recesywnego. Teraz, mimo że osoba może być fenotypem dominującym Aaalbo AAbyć dominującym, ponieważ ma recesywne dziecko, musi być Aaheterozygotyczna. Możesz to zrobić dla wszystkich innych ludzi. W przypadku nie masz żadnych informacji, które pozwala, aby dowiedzieć się drugi allel, można to zrobić tak: A_.

Twoje zadanie

  • Otrzymasz wykres rodowy w formie listy pokoleń, jak [GenI, GenII, etc.]w dowolnym rozsądnym formacie.
  • Każde pokolenie będzie listą ciągów, przy czym każdy ciąg reprezentuje osobę.
  • Ludzie składają się z trzech części - identyfikatora, ich fenotypu i „powiązań”.
  • Ich identyfikator to pojedyncza postać ascii do wydrukowania, która jest unikalna w całym drzewie innym niż Alub a. (Nie, na wykresie nie będzie więcej niż 95 osób).
  • Ich fenotyp jest jednym Aalbo a, Abędąc allel dominujący i ajest recesywny.
  • Ich połączenia są sekwencją identyfikatorów innych osób, z którymi mają powiązania.
  • Związkiem w tym samym pokoleniu jest małżeństwo, w różnych pokoleniach dziecko i rodzic.
  • Połączenia są powtarzane po obu stronach (tj. Mąż powiedział, że jest mężem żony, a żona mówi, że jest mężem żony).
  • Musisz jak najwięcej dowiedzieć się o genotypach wszystkich.
  • Zwróć tę samą listę, z wyjątkiem tego, że zamiast ludzi umieść swoje genotypy w tej samej pozycji.
  • Genotyp musi być wyprowadzany w takiej kolejności, a Aanie aA.
  • Trochę swobody w zakresie formatu wejściowego jest w porządku.
  • To jest golf golfowy, więc wygrywa najkrótsza odpowiedź w bajtach .

Przykłady

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

Premia

  • -30 bajtów, jeśli masz również do czynienia z niekompletnością i współdominacją . Po wykryciu trzech fenotypów zamiast dwóch na całym wykresie zastosuj niekompletną / ko-dominację w swoim algorytmie.
Maltysen
źródło
Czy wolno nam tylko zmodyfikować Ai ai zostawić identyfikatory i połączenia jak jest (czyli [["0A12","1A02"],["2A301","3a2"]]staje się [["0A_12","1A_02"],["2A_301","3aa2"]]zamiast [["A_","A_"],["A_","aa"]])?
Kevin Cruijssen

Odpowiedzi:

2

05AB1E , 39 bajtów

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

Port mojej odpowiedzi Java .

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

ε                     # 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
źródło
1

Java 10, 356 349 340 bajtów

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;}

Wypróbuj online.

Ogólne wyjaśnienie:

1) Każdy azawsze się stanieaa

2a) Jeśli dziecko Ama rodziców aai Astanie się Aa
2b) Jeśli dziecko Ama rodziców Ai Astanie się A_
2c) (Dziecko nie Amoże mieć rodziców aai aa)

3a) Jeśli rodzic Ama co najmniej jedno dziecko a, stanie się Aa
3b) Jeśli rodzic Ama tylko dzieci A, stanie sięA_

Objaśnienie kodu:

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
źródło