Analisar RNA em códons

18

Introdução

O RNA é o primo menos famoso do DNA. Seu principal objetivo é controlar a produção de proteínas nas células através de um processo chamado tradução . Nesse desafio, sua tarefa é implementar uma parte desse processo em que o RNA é dividido em códons .

Esse desafio está relacionado tematicamente, mas se concentra em outra parte do processo de tradução.

Codons

Pensaremos no RNA como uma longa corda sobre o alfabeto dos pares de bases AUCG. Na tradução, o RNA é dividido em pedaços não sobrepostos de três pares de bases, chamados códons. O processo começa com um codão de iniciação , AUGe as extremidades a um codão de paragem , um dos UAA, UAGou UGA. Cada códon (exceto os códons de parada) corresponde a um aminoácido, e a cadeia resultante de aminoácidos forma a proteína.

Entrada

Sua entrada é uma sequência não vazia de RNA.

Resultado

Sua saída é a lista de códons em que o RNA é dividido, em qualquer formato razoável. Nesse modelo simplificado, o processo começa no códon de início mais à esquerdaAUG , incluído na saída. Ele termina quando um códon de parada é encontrado ou quando o RNA fica vazio. Se a entrada não contiver um códon inicial, a saída será uma lista vazia.

Exemplos

Considere a sequência de entrada

ACAUGGAUGGACUGUAACCCCAUGC

A análise começa na ocorrência mais à esquerda de AUG, no índice 2. Continua da seguinte forma:

AC AUG GAU GGA CUG UAA CCCCAUGC
   *   ^   ^   ^   +

O códon marcado com *é o códon inicial e os marcados com ^também fazem parte da saída. O codão de parada é marcado com +. A saída correta é

AUG,GAU,GGA,CUG

Para a entrada mais curta

ACAUGGAUGGACUGU

o processo continua

AC AUG GAU GGA CUG U
   *   ^   ^   ^

Desta vez, um códon de parada não é encontrado, portanto, o processo para quando ficamos sem pares de bases. A saída é a mesma que acima.

Regras e pontuação

Você pode escrever um programa completo de uma função. A menor contagem de bytes vence e as brechas padrão não são permitidas.

Casos de teste

GGUACGGAUU -> 
GGCGAAAUCGAUGCC -> AUG
ACAUGGAUGGACUGU -> AUG,GAU,GGA,CUG
AUGACGUGAUGCUUGA -> AUG,ACG
UGGUUAGAAUAAUGAGCUAG -> AUG,AGC
ACAUGGAUGGACUGUAACCCCAUGC -> AUG,GAU,GGA,CUG
CUAAGAUGGCAUGAGUAAUGAAUGGAG -> AUG,GCA
AAUGGUUUAAUAAAUGUGAUAUGAUGAUA -> AUG,GUU
UGUCACCAUGUAAGGCAUGCCCAAAAUCAG -> AUG
UAUAGAUGGUGAUGAUGCCAUGAGAUGCAUGUUAAU -> AUG,GUG,AUG,AUG,CCA
AUGCUUAUGAAUGGCAUGUACUAAUAGACUCACUUAAGCGGUGAUGAA -> AUG,CUU,AUG,AAU,GGC,AUG,UAC
UGAUAGAUGUAUGGAUGGGAUGCUCAUAGCUAUAAAUGUUAAAGUUAGUCUAAUGAUGAGUAGCCGAUGGCCUAUGAUGCUGAC -> AUG,UAU,GGA,UGG,GAU,GCU,CAU,AGC,UAU,AAA,UGU
Zgarb
fonte
13
A relação do DNA com o RNA e com a proteína já me foi explicada em termos computacionais que eu pude entender: o DNA equivale a um programa em um disco rígido; O RNA é igual ao programa carregado na memória; e proteína equivale aos dados de saída produzidos como resultado da execução do programa.
Digital Trauma
4
O dogma da biologia molecular é "o DNA produz RNA produz proteínas". Portanto, o DNA é bastante raro e o RNA é menos famoso, mas muito mais comum. A proteína é mais comum de todas.
Level River St
1
@DigitalTrauma: Como geneticista, preciso ressaltar que essa analogia é lamentavelmente inadequada para descrever a realidade de como o DNA funciona. O DNA não é uma coisa morta à espera de ser transcrita no RNA para que ele possa fazer alguma coisa.
Jack Aidley
O que realmente ocorre na prática se um pedaço de mRNA termina antes de um códon de parada (como no exemplo simples), significando que não há tripleto de parada para que um fator de liberação se ligue?
Reinstate Monica - ζ-- 16/01
1
O conteúdo do disco rígido do @Jack também não é necessariamente algo morto - atualizações, atualizações automáticas etc., embora, claro, não seja auto-reparável na medida em que eu entendo que o DNA seja. Mas você está certo - é uma analogia fraca. No entanto, acho que o meu eu não geneticista se aproximou um pouco da compreensão de um leigo
Digital Trauma

Respostas:

9

Retina , 39 38 32 30 bytes

M!`AUG|\B\G...
U(AA|AG|GA)\D*

O avanço de linha à direita é significativo.

Saída como uma lista separada por avanço de linha.

Experimente online.

Explicação

M!`AUG|\B\G...

Este é o estágio de correspondência que transforma a entrada em uma lista separada por avanço de linha de todas as correspondências (devido à !). O regex em si corresponde a todos os códons a partir do primeiro AUG. Conseguimos isso com duas opções separadas. AUGcorresponde incondicionalmente, para que possa iniciar a lista de correspondências. A segunda correspondência pode ser qualquer códon ( ...corresponde a três caracteres), mas \Gé uma âncora especial que garante que isso possa corresponder apenas após outra correspondência. O único problema é que \Gtambém corresponde no início da string, o que não queremos. Como a entrada consiste apenas em caracteres de palavra, usamos \B(qualquer posição que não seja um limite de palavra) para garantir que essa correspondência não seja usada no início da entrada.

U(AA|AG|GA)\D*

U(AA|AG|GA)Ele encontra o primeiro códon de parada, correspondente e tudo depois dele, e o remove da cadeia de caracteres. Desde que o primeiro estágio dividiu os códons em linhas separadas, sabemos que essa correspondência está alinhada adequadamente com o códon inicial. Usamos \D(sem dígitos) para corresponder a qualquer caractere, pois .não passamos dos feeds de linha e a entrada não contém dígitos.

Martin Ender
fonte
5

Haskell, 115 112 bytes

import Data.Lists
fst.break(\e->elem e["UAA","UAG","UGA"]||length e<3).chunksOf 3.snd.spanList((/="AUG").take 3)

Exemplo de uso:

*Main> ( fst.break(\e->elem e["UAA","UAG","UGA"]||length e<3).chunksOf 3.snd.spanList((/="AUG").take 3) ) "AUGCUUAUGAAUGGCAUGUACUAAUAGACUCACUUAAGCGGUGAUGAA"
["AUG","CUU","AUG","AAU","GGC","AUG","UAC"]

Como funciona:

                spanList((/="AUG").take 3)  -- split input at the first "AUG"
             snd                            -- take 2nd part ("AUG" + rest)
     chunksOf 3                             -- split into 3 element lists
fst.break(\e->                              -- take elements from this list
           elem e["UAA","UAG","UGA"]||      -- as long as we don't see end codons
           length e<3)                      -- or run out of full codons 
nimi
fonte
1

JavaScript 88 82 70 69 caracteres

s=>/AUG(...)+?(?=(U(AA|AG|GA)|$))/.exec(s)[0].match(/.../g).join(",")

Exemplo de uso:

(s=>/AUG(...)+?(?=(U(AA|AG|GA)|$))/.exec(s)[0].match(/.../g).join(","))("ACAUGGAUGGACUGUAACCCCAUGC")
Benjamin Gruenbaum
fonte
Isso não falha na entrada sem um códon de parada?
Flambino 16/01
1
Você está certo, eu não vi que era uma opção, fixando
Benjamin Gruenbaum
Tente s=>/AUG(...)+?(?=(U(AA|AG|GA)|$))/.exec(s)[0].match(/.../g).
Mama Fun Roll
Ainda falha nos códons de parada. (Tente o caso de teste 3)
user81655 17/16/16
1

Python 2, 185 bytes

i=input()
o=[]
if i.find('AUG')>=0:i=map(''.join,zip(*[iter(i[i.find('AUG'):])]*3))
else:print "";exit()
for j in i:
 if j not in['UGA','UAA','UAG']:o+=[j]
 else:break
print ','.join(o)

Explicação Defina icomo entrada. Divida-o de 'AUG' até o fim. Divida em seqüências de três. Verifique se interrompe o codão e corte.

Experimente aqui

TanMath
fonte
1

MATL , 57 bytes

j'AUG(...)*?(?=(UAA|UAG|UGA|.?.?$))'XXtn?1X)tnt3\-:)3[]e!

Isso usa a versão atual (9.3.1) do idioma / compilador.

Entrada e saída são através de stdin e stdout. A saída é separada por quebras de linha.

Exemplo

>> matl
 > j'AUG(...)*?(?=(UAA|UAG|UGA|.?.?$))'XXtn?1X)tnt3\-:)3[]e!
 >
> ACAUGGAUGGACUGUAACCCCAUGC
AUG
GAU
GGA
CUG

EDIT (12 de junho de 2016): para se adaptar às mudanças de idioma, []deve ser removido. O link abaixo inclui essa modificação

Experimente online!

Explicação

O código é baseado na expressão regular

AUG(...)*?(?=(UAA|UAG|UGA|.?.?$))

Subsequências começando com este partidas AUG, que contêm grupos de três caracteres ( ...) e que terminam em ambos UAA, UAG, ou UGA; ou terminando no final da string e, nesse caso, pode haver um último grupo incompleto ( .?.?$). Lookahead ( (?=...)) é usado para que os códons de parada não façam parte da correspondência. A correspondência é lenta ( *?) para terminar no primeiro stop codão encontrado, se houver.

j                                     % input string
'AUG(...)*?(?=(UAA|UAG|UGA|.?.?$))'   % regex
XX                                    % apply it. Push cell array of matched substrings
tn?                                   % if non-empty
1X)                                   % get first substring
tnt3\-:)                              % make length the largest possible multiple of 3
3[]e!                                 % reshape into rows of 3 columns
                                      % implicit endif
                                      % implicit display
Luis Mendo
fonte
0

Ruby, 97 95 78 75 62 bytes

->(r){r.scan(/AUG|\B\G.../).join(?,).sub(/,U(AA|AG|GA).*/,'')}

Eu não jogo muito, então tenho certeza de que isso pode ser melhorado.

Edit: Roubou o excelente \B\Gtruque emprestado de Martin Büttner

Flambino
fonte