Calcular um pedigree

22

Uma pequena lição de genética

Quando você tem acesso apenas aos traços ou fenótipos visíveis de alguém, geralmente é usado um pedigree da história da família para descobrir as informações genéticas reais ou o genótipo de cada membro da família.

Ao lidar com a dominância simples como seremos, um gráfico simples de linhagem será suficiente para descobrir os alelos, ou a versão dos genes que eles possuem, de cada pessoa. Em domínio simples, uma pessoa com um alelo dominante (indicado com uma letra maiúscula) sempre terá a característica que essa versão representa, independentemente do outro alelo. São necessários dois alelos recessivos (indicados com uma letra minúscula) para que essa versão seja expressa. Em outras palavras, o alelo dominante sempre mascara a versão recessiva desse gene. Aqui está um exemplo de um gráfico de linhagem:

QUADRO DE PEDIGREE

Cada linha aqui é uma geração. Círculos são femininos, quadrados masculinos, linhas horizontais são casamento, linhas verticais, filhos. Bem simples. Preto significa fenótipo recessivo, branco, dominante. Começando do topo, (suponha que os alelos sejam Ae a), sabemos que a pessoa 2 tem aa, recessivo homozigoto, porque essa é a única opção possível para o fenótipo recessivo. Agora, mesmo que a pessoa um possa ser um fenótipo dominante, Aaou AApor ser dominante, porque ele tem um filho recessivo, ele deve ser Aaou heterozigoto. Você pode fazer isso para todas as outras pessoas. No caso de você não ter qualquer informação que lhe permite descobrir o segundo alelo, isso pode ser feito da seguinte forma: A_.

Sua tarefa

  • Você receberá um gráfico de linhagem na forma de uma lista de gerações, como [GenI, GenII, etc.]em qualquer formato sensato.
  • Cada geração será uma lista de cadeias, cada uma representando uma pessoa.
  • As pessoas são compostas de três partes - uma identificação, seu fenótipo e suas "conexões".
  • Seu ID é um caractere ASCII imprimível único na árvore inteira, exceto Aou a. (Não, não haverá mais de 95 pessoas no gráfico).
  • Seu fenótipo é um de Aou a, Asendo o alelo dominante e asendo recessivo.
  • Suas conexões são uma sequência de IDs de outras pessoas com as quais eles têm conexões.
  • Uma conexão na mesma geração é casamento, em gerações diferentes é filho e pai.
  • As conexões são repetidas nos dois lados (ou seja, o marido diz que é marido da esposa e a esposa diz que é marido da esposa).
  • Você tem que descobrir os genótipos de todos, tanto quanto possível.
  • Retorne a mesma lista, exceto que, em vez de pessoas, coloque seus genótipos na mesma posição.
  • O genótipo deve ser emitido em ordem, em Aavez de aA.
  • Uma pequena margem de manobra no formato de entrada está correta.
  • Este é o código-golfe, pelo que a resposta mais curta em bytes vence.

Exemplos

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

Bônus

  • -30 bytes se você lidar com incompleto e co-domínio também. Na detecção de três fenótipos em vez de dois no gráfico inteiro, aplique dominância incompleta / co ao seu algoritmo.
Maltysen
fonte
É permitido modificar apenas o Ae ae deixar os ids e conexões como é (ou seja, [["0A12","1A02"],["2A301","3a2"]]torna-se [["0A_12","1A_02"],["2A_301","3aa2"]], em vez de [["A_","A_"],["A_","aa"]])?
Kevin Cruijssen 28/02

Respostas:

2

05AB1E , 39 bytes

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

Porta da minha resposta Java .

Experimente online ou verifique todos os casos de teste .

Explicação:

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

Experimente online.

Explicação geral:

1) Qualquer aserá sempreaa

2a) Se uma criança Atem pais aae A, ela se tornará Aa
2b) Se uma criança Ativer pais Ae A, ela se tornará A_
2c) (Não é possível que uma criança Atenha pais aae aa)

3a) Se um dos pais Ativer pelo menos um filho a, ele se tornará Aa
3b) Se um dos pais Ativer apenas filhos A, ele se tornaráA_

Explicação do 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
fonte