Parsuj RNA na kodony

18

Wprowadzenie

RNA jest mniej znanym kuzynem DNA. Jego głównym celem jest kontrola produkcji białek w komórkach poprzez proces zwany translacją . W tym wyzwaniu Twoim zadaniem jest wdrożenie części tego procesu, w której RNA jest dzielony na kodony .

To wyzwanie jest powiązane tematycznie, ale koncentruje się na innej części procesu tłumaczenia.

Codons

Będziemy myśleć RNA jako długi ciąg nad alfabetem par bazowych AUCG. W tłumaczeniu RNA dzieli się na niepochodzące na siebie fragmenty trzech par zasad, zwane kodonami. Proces rozpoczyna się w kodonie startowym , AUGi kończy się kodonem stop , jednego UAA, UAGalbo UGA. Każdy kodon (oprócz kodonów stop) odpowiada aminokwasowi, a powstały ciąg aminokwasów tworzy białko.

Wejście

Twoje dane wejściowe to niepusty ciąg RNA.

Wynik

Twój wynik to lista kodonów, w których RNA jest podzielony, w dowolnym rozsądnym formacie. W tym uproszczonym modelu proces rozpoczyna się od lewego kodonu start AUG, który jest zawarty w wyjściu. Kończy się, gdy napotkamy kodon stop lub skończy nam się RNA. Jeśli dane wejściowe nie zawierają kodonu początkowego, dane wyjściowe powinny być pustą listą.

Przykłady

Rozważ sekwencję wejściową

ACAUGGAUGGACUGUAACCCCAUGC

Analiza rozpoczyna się przy wystąpieniu skrajnie po lewej stronie AUGindeksu 2. Kontynuuje się w następujący sposób:

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

Kodon oznaczony *jest kodonem start, a te oznaczone jako ^są również częścią wyniku. Kodon stop jest oznaczony +. Prawidłowe wyjście to

AUG,GAU,GGA,CUG

Dla krótszych danych wejściowych

ACAUGGAUGGACUGU

proces idzie

AC AUG GAU GGA CUG U
   *   ^   ^   ^

Tym razem kodon stop nie został napotkany, więc proces zatrzymuje się, gdy zabraknie par zasad. Dane wyjściowe są takie same jak powyżej.

Zasady i punktacja

Możesz napisać pełny program funkcji. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Przypadki testowe

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
źródło
13
Związek DNA z RNA z białkiem został mi kiedyś wyjaśniony w kategoriach komputerowych, które mogłem zrozumieć: DNA oznacza program na dysku twardym; RNA odpowiada programowi załadowanemu do pamięci; a białko to dane wyjściowe wytworzone w wyniku uruchomienia tego programu.
Cyfrowa trauma
4
Dogmat biologii molekularnej brzmi: „DNA wytwarza RNA z białka”. Więc DNA jest dość rzadkie, a RNA jest mniej znane, ale o wiele bardziej powszechne. Białko jest najbardziej powszechne ze wszystkich.
Level River St
1
@DigitalTrauma: Jako genetyk muszę podkreślić, że ta analogia jest bardzo nieodpowiednia do opisania rzeczywistości działania DNA. DNA nie jest czymś martwym, czekającym na transkrypcję do RNA, aby mógł coś zrobić.
Jack Aidley,
Co faktycznie dzieje się w praktyce, jeśli fragment mRNA kończy się przed kodonem stop (jak w prostym przykładzie), co oznacza brak trypletu stop dla czynnika wiążącego?
Przywróć Monikę - ζ--
1
@Jack zawartość dysku twardego niekoniecznie jest martwą rzeczą - aktualizacje, automatyczne aktualizacje itp., Choć oczywiście nie samoleczenia w zakresie, w jakim rozumiem DNA. Ale masz rację - to słaba analogia. Wydaje mi się jednak, że moje niegenetyczne geneza zbliżyła się do zrozumienia dla laika
Digital Trauma

Odpowiedzi:

9

Retina , 39 38 32 30 bajtów

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

Końcowe podawanie linii jest znaczące.

Dane wyjściowe w postaci listy oddzielonej od linii.

Wypróbuj online.

Wyjaśnienie

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

Jest to etap dopasowania, który przekształca dane wejściowe w listę wszystkich dopasowań oddzieloną od linii (z powodu !). Sam regex pasuje do każdego kodonu, zaczynając od pierwszego AUG. Osiągamy to dzięki dwóm oddzielnym opcjom. AUGdopasowuje bezwarunkowo, aby mógł rozpocząć listę dopasowań. Drugim dopasowaniem może być dowolny kodon ( ...pasuje do dowolnych trzech znaków), ale \Gjest to specjalna kotwica, która zapewnia, że ​​może się dopasować dopiero po kolejnym dopasowaniu. Jedynym problemem jest to, że \Gpasuje również na początku łańcucha, czego nie chcemy. Ponieważ dane wejściowe składają się wyłącznie ze znaków słownych, używamy \B(dowolnej pozycji, która nie jest granicą słowa), aby upewnić się, że to dopasowanie nie będzie używane na początku wprowadzania.

U(AA|AG|GA)\D*

Znajduje pierwszy kodon stop, dopasowany, a U(AA|AG|GA)także wszystko po nim i usuwa go z łańcucha. Ponieważ pierwszy etap dzieli kodony na osobne linie, wiemy, że to dopasowanie jest odpowiednio wyrównane z kodonem start. Używamy \D(nie cyfr), aby dopasować dowolny znak, ponieważ .nie przekroczyłby linii, a dane wejściowe nie będą zawierać cyfr.

Martin Ender
źródło
5

Haskell, 115 112 bajtów

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

Przykład użycia:

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

Jak to działa:

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

JavaScript 88 82 70 69 znaków

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

Przykład użycia:

(s=>/AUG(...)+?(?=(U(AA|AG|GA)|$))/.exec(s)[0].match(/.../g).join(","))("ACAUGGAUGGACUGUAACCCCAUGC")
Benjamin Gruenbaum
źródło
Czy to nie zawiedzie dla wejścia bez kodonu stop?
Flambino
1
Masz rację, nie widziałem, żeby to była opcja, naprawianie
Benjamin Gruenbaum,
Spróbować s=>/AUG(...)+?(?=(U(AA|AG|GA)|$))/.exec(s)[0].match(/.../g).
Mama Fun Roll
Nadal nie działa w przypadku kodonów stop. (Wypróbuj test case 3)
user81655
1

Python 2, 185 bajtów

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)

Objaśnienie Ustaw ina wejście. Podziel go od „AUG” do końca. Podzielony na trzy ciągi. Sprawdź, czy kodon stop i wytnij.

Wypróbuj tutaj

TanMath
źródło
1

MATL , 57 bajtów

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

To używa bieżącej wersji (9.3.1) języka / kompilatora.

Wejście i wyjście odbywa się poprzez standardowe wejście i standardowe wyjście. Dane wyjściowe są oddzielone podziałem wiersza.

Przykład

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

EDYCJA (12 czerwca 2016 r.): Aby dostosować się do zmian w języku, [] należy go usunąć. Poniższy link zawiera tę modyfikację

Wypróbuj online!

Wyjaśnienie

Kod oparty jest na wyrażeniu regularnym

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

Dopasowuje podciągi, począwszy od dnia AUG, zawierające grupy trzech znaków ( ...), a kończąc na jeden UAA, UAGlub UGA; lub kończące się na końcu ciągu, w tym przypadku może być jeszcze jedna niekompletna grupa ( .?.?$). Funkcja Lookahead ( (?=...)) jest używana, aby kodony stop nie były częścią dopasowania. Dopasowanie jest lazy ( *?), aby zakończyć na pierwszym znalezionym kodonie stop, jeśli taki istnieje.

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

Ruby, 97 95 78 75 62 bajtów

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

Nie gram dużo w golfa, więc jestem pewien, że można to poprawić.

Edycja: Stole pożyczył doskonałą \B\Gsztuczkę Martina Büttnera

Flambino
źródło